Compare commits
45 Commits
feat/kolay
...
b4effc8545
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4effc8545 | ||
|
|
6bd210075f | ||
|
|
716f7bb3fb | ||
|
|
f27f3ffaac | ||
|
|
ff66480227 | ||
|
|
b3dd36fa72 | ||
|
|
55eb32b22a | ||
|
|
8cf0c3267d | ||
|
|
569b9e5da2 | ||
|
|
acb3b9d557 | ||
|
|
1583d424fd | ||
|
|
60e81e266d | ||
|
|
736a6fabf0 | ||
|
|
65d630d754 | ||
|
|
e74710a20a | ||
|
|
9139977cd6 | ||
|
|
a1b2c4b069 | ||
|
|
36008bb72a | ||
|
|
2c542e7756 | ||
|
|
dc6d894a37 | ||
|
|
40a1c8ef8e | ||
|
|
7288c926d0 | ||
|
|
d93cf742ff | ||
|
|
209d203fe8 | ||
|
|
1d0328d8eb | ||
|
|
d5235310d5 | ||
|
|
2c02e3d7e9 | ||
|
|
fc146b0e18 | ||
|
|
92adfad464 | ||
|
|
669ff9b43a | ||
|
|
486f99c897 | ||
|
|
6d8699005c | ||
|
|
43457df3a9 | ||
|
|
312c06abbc | ||
|
|
0aaf705be2 | ||
|
|
fb44349bf8 | ||
| d5e23c0ce9 | |||
|
|
2ce0d417dc | ||
| fef13ce7b8 | |||
| 17caaab5fb | |||
| f815d1e861 | |||
|
|
1105415284 | ||
|
|
03107841ac | ||
| 5ce68c7932 | |||
|
|
307e778d62 |
@@ -12,6 +12,12 @@
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["run", "dev", "--", "-p", "3100"],
|
||||
"port": 3100
|
||||
},
|
||||
{
|
||||
"name": "prod-3100",
|
||||
"runtimeExecutable": "pnpm",
|
||||
"runtimeArgs": ["start", "-p", "3100"],
|
||||
"port": 3100
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
name: ui-ux-pro-max
|
||||
description: "UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 9 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn/ui MCP for component search and examples."
|
||||
description: "UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 4 stacks (Next.js, React, Tailwind, shadcn/ui). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, .html, .tsx. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn/ui MCP for component search and examples."
|
||||
---
|
||||
|
||||
# UI/UX Pro Max - Design Intelligence
|
||||
|
||||
Comprehensive design guide for web and mobile applications. Contains 50+ styles, 97 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 9 technology stacks. Searchable database with priority-based recommendations.
|
||||
Comprehensive design guide for this Next.js + React + Tailwind + shadcn/ui codebase. Contains 50+ styles, 97 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 4 technology stacks. Searchable database with priority-based recommendations.
|
||||
|
||||
## When to Apply
|
||||
|
||||
@@ -128,7 +128,7 @@ Extract key information from user request:
|
||||
- **Product type**: SaaS, e-commerce, portfolio, dashboard, landing page, etc.
|
||||
- **Style keywords**: minimal, playful, professional, elegant, dark mode, etc.
|
||||
- **Industry**: healthcare, fintech, gaming, education, etc.
|
||||
- **Stack**: React, Vue, Next.js, or default to `html-tailwind`
|
||||
- **Stack**: Next.js / React / shadcn (default: `nextjs`)
|
||||
|
||||
### Step 2: Generate Design System (REQUIRED)
|
||||
|
||||
@@ -167,15 +167,15 @@ python3 .claude/skills/ui-ux-pro-max/scripts/search.py "<keyword>" --domain <dom
|
||||
| Alternative fonts | `typography` | `--domain typography "elegant luxury"` |
|
||||
| Landing structure | `landing` | `--domain landing "hero social-proof"` |
|
||||
|
||||
### Step 4: Stack Guidelines (Default: html-tailwind)
|
||||
### Step 4: Stack Guidelines (Default: nextjs)
|
||||
|
||||
Get implementation-specific best practices. If user doesn't specify a stack, **default to `html-tailwind`**.
|
||||
Get implementation-specific best practices. If user doesn't specify a stack, **default to `nextjs`**. For component patterns use `shadcn`; for Tailwind utilities use `html-tailwind`.
|
||||
|
||||
```bash
|
||||
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "<keyword>" --stack html-tailwind
|
||||
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "<keyword>" --stack nextjs
|
||||
```
|
||||
|
||||
Available stacks: `html-tailwind`, `react`, `nextjs`, `vue`, `svelte`, `swiftui`, `react-native`, `flutter`, `shadcn`
|
||||
Available stacks: `nextjs`, `react`, `shadcn`, `html-tailwind`
|
||||
|
||||
---
|
||||
|
||||
@@ -200,15 +200,10 @@ Available stacks: `html-tailwind`, `react`, `nextjs`, `vue`, `svelte`, `swiftui`
|
||||
|
||||
| Stack | Focus |
|
||||
|-------|-------|
|
||||
| `html-tailwind` | Tailwind utilities, responsive, a11y (DEFAULT) |
|
||||
| `nextjs` | SSR, routing, images, API routes (DEFAULT) |
|
||||
| `react` | State, hooks, performance, patterns |
|
||||
| `nextjs` | SSR, routing, images, API routes |
|
||||
| `vue` | Composition API, Pinia, Vue Router |
|
||||
| `svelte` | Runes, stores, SvelteKit |
|
||||
| `swiftui` | Views, State, Navigation, Animation |
|
||||
| `react-native` | Components, Navigation, Lists |
|
||||
| `flutter` | Widgets, State, Layout, Theming |
|
||||
| `shadcn` | shadcn/ui components, theming, forms, patterns |
|
||||
| `html-tailwind` | Tailwind utilities, responsive, a11y |
|
||||
|
||||
---
|
||||
|
||||
@@ -220,7 +215,7 @@ Available stacks: `html-tailwind`, `react`, `nextjs`, `vue`, `svelte`, `swiftui`
|
||||
- Product type: Beauty/Spa service
|
||||
- Style keywords: elegant, professional, soft
|
||||
- Industry: Beauty/Wellness
|
||||
- Stack: html-tailwind (default)
|
||||
- Stack: nextjs (default)
|
||||
|
||||
### Step 2: Generate Design System (REQUIRED)
|
||||
|
||||
@@ -243,7 +238,7 @@ python3 .claude/skills/ui-ux-pro-max/scripts/search.py "elegant luxury serif" --
|
||||
### Step 4: Stack Guidelines
|
||||
|
||||
```bash
|
||||
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "layout responsive form" --stack html-tailwind
|
||||
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "layout responsive form" --stack nextjs
|
||||
```
|
||||
|
||||
**Then:** Synthesize design system + detailed searches and implement the design.
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
|
||||
1,Widgets,Use StatelessWidget when possible,Immutable widgets are simpler,StatelessWidget for static UI,StatefulWidget for everything,class MyWidget extends StatelessWidget,class MyWidget extends StatefulWidget (static),Medium,https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
|
||||
2,Widgets,Keep widgets small,Single responsibility principle,Extract widgets into smaller pieces,Large build methods,Column(children: [Header() Content()]),500+ line build method,Medium,
|
||||
3,Widgets,Use const constructors,Compile-time constants for performance,const MyWidget() when possible,Non-const for static widgets,const Text('Hello'),Text('Hello') for literals,High,https://dart.dev/guides/language/language-tour#constant-constructors
|
||||
4,Widgets,Prefer composition over inheritance,Combine widgets using children,Compose widgets,Extend widget classes,Container(child: MyContent()),class MyContainer extends Container,Medium,
|
||||
5,State,Use setState correctly,Minimal state in StatefulWidget,setState for UI state changes,setState for business logic,setState(() { _counter++; }),Complex logic in setState,Medium,https://api.flutter.dev/flutter/widgets/State/setState.html
|
||||
6,State,Avoid setState in build,Never call setState during build,setState in callbacks only,setState in build method,onPressed: () => setState(() {}),build() { setState(); },High,
|
||||
7,State,Use state management for complex apps,Provider Riverpod BLoC,State management for shared state,setState for global state,Provider.of<MyState>(context),Global setState calls,Medium,
|
||||
8,State,Prefer Riverpod or Provider,Recommended state solutions,Riverpod for new projects,InheritedWidget manually,ref.watch(myProvider),Custom InheritedWidget,Medium,https://riverpod.dev/
|
||||
9,State,Dispose resources,Clean up controllers and subscriptions,dispose() for cleanup,Memory leaks from subscriptions,@override void dispose() { controller.dispose(); },No dispose implementation,High,
|
||||
10,Layout,Use Column and Row,Basic layout widgets,Column Row for linear layouts,Stack for simple layouts,"Column(children: [Text(), Button()])",Stack for vertical list,Medium,https://api.flutter.dev/flutter/widgets/Column-class.html
|
||||
11,Layout,Use Expanded and Flexible,Control flex behavior,Expanded to fill space,Fixed sizes in flex containers,Expanded(child: Container()),Container(width: 200) in Row,Medium,
|
||||
12,Layout,Use SizedBox for spacing,Consistent spacing,SizedBox for gaps,Container for spacing only,SizedBox(height: 16),Container(height: 16),Low,
|
||||
13,Layout,Use LayoutBuilder for responsive,Respond to constraints,LayoutBuilder for adaptive layouts,Fixed sizes for responsive,LayoutBuilder(builder: (context constraints) {}),Container(width: 375),Medium,https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html
|
||||
14,Layout,Avoid deep nesting,Keep widget tree shallow,Extract deeply nested widgets,10+ levels of nesting,Extract widget to method or class,Column(Row(Column(Row(...)))),Medium,
|
||||
15,Lists,Use ListView.builder,Lazy list building,ListView.builder for long lists,ListView with children for large lists,"ListView.builder(itemCount: 100, itemBuilder: ...)",ListView(children: items.map(...).toList()),High,https://api.flutter.dev/flutter/widgets/ListView-class.html
|
||||
16,Lists,Provide itemExtent when known,Skip measurement,itemExtent for fixed height items,No itemExtent for uniform lists,ListView.builder(itemExtent: 50),ListView.builder without itemExtent,Medium,
|
||||
17,Lists,Use keys for stateful items,Preserve widget state,Key for stateful list items,No key for dynamic lists,ListTile(key: ValueKey(item.id)),ListTile without key,High,
|
||||
18,Lists,Use SliverList for custom scroll,Custom scroll effects,CustomScrollView with Slivers,Nested ListViews,CustomScrollView(slivers: [SliverList()]),ListView inside ListView,Medium,https://api.flutter.dev/flutter/widgets/SliverList-class.html
|
||||
19,Navigation,Use Navigator 2.0 or GoRouter,Declarative routing,go_router for navigation,Navigator.push for complex apps,GoRouter(routes: [...]),Navigator.push everywhere,Medium,https://pub.dev/packages/go_router
|
||||
20,Navigation,Use named routes,Organized navigation,Named routes for clarity,Anonymous routes,Navigator.pushNamed(context '/home'),Navigator.push(context MaterialPageRoute()),Low,
|
||||
21,Navigation,Handle back button (PopScope),Android back behavior and predictive back (Android 14+),Use PopScope widget (WillPopScope is deprecated),Use WillPopScope,"PopScope(canPop: false, onPopInvoked: (didPop) => ...)",WillPopScope(onWillPop: ...),High,https://api.flutter.dev/flutter/widgets/PopScope-class.html
|
||||
22,Navigation,Pass typed arguments,Type-safe route arguments,Typed route arguments,Dynamic arguments,MyRoute(id: '123'),arguments: {'id': '123'},Medium,
|
||||
23,Async,Use FutureBuilder,Async UI building,FutureBuilder for async data,setState for async,FutureBuilder(future: fetchData()),fetchData().then((d) => setState()),Medium,https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
|
||||
24,Async,Use StreamBuilder,Stream UI building,StreamBuilder for streams,Manual stream subscription,StreamBuilder(stream: myStream),stream.listen in initState,Medium,https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html
|
||||
25,Async,Handle loading and error states,Complete async UI states,ConnectionState checks,Only success state,if (snapshot.connectionState == ConnectionState.waiting),No loading indicator,High,
|
||||
26,Async,Cancel subscriptions,Clean up stream subscriptions,Cancel in dispose,Memory leaks,subscription.cancel() in dispose,No subscription cleanup,High,
|
||||
27,Theming,Use ThemeData,Consistent theming,ThemeData for app theme,Hardcoded colors,Theme.of(context).primaryColor,Color(0xFF123456) everywhere,Medium,https://api.flutter.dev/flutter/material/ThemeData-class.html
|
||||
28,Theming,Use ColorScheme,Material 3 color system,ColorScheme for colors,Individual color properties,colorScheme: ColorScheme.fromSeed(),primaryColor: Colors.blue,Medium,
|
||||
29,Theming,Access theme via context,Dynamic theme access,Theme.of(context),Static theme reference,Theme.of(context).textTheme.bodyLarge,TextStyle(fontSize: 16),Medium,
|
||||
30,Theming,Support dark mode,Respect system theme,darkTheme in MaterialApp,Light theme only,"MaterialApp(theme: light, darkTheme: dark)",MaterialApp(theme: light),Medium,
|
||||
31,Animation,Use implicit animations,Simple animations,AnimatedContainer AnimatedOpacity,Explicit for simple transitions,AnimatedContainer(duration: Duration()),AnimationController for fade,Low,https://api.flutter.dev/flutter/widgets/AnimatedContainer-class.html
|
||||
32,Animation,Use AnimationController for complex,Fine-grained control,AnimationController with Ticker,Implicit for complex sequences,AnimationController(vsync: this),AnimatedContainer for staggered,Medium,
|
||||
33,Animation,Dispose AnimationControllers,Clean up animation resources,dispose() for controllers,Memory leaks,controller.dispose() in dispose,No controller disposal,High,
|
||||
34,Animation,Use Hero for transitions,Shared element transitions,Hero for navigation animations,Manual shared element,Hero(tag: 'image' child: Image()),Custom shared element animation,Low,https://api.flutter.dev/flutter/widgets/Hero-class.html
|
||||
35,Forms,Use Form widget,Form validation,Form with GlobalKey,Individual validation,Form(key: _formKey child: ...),TextField without Form,Medium,https://api.flutter.dev/flutter/widgets/Form-class.html
|
||||
36,Forms,Use TextEditingController,Control text input,Controller for text fields,onChanged for all text,final controller = TextEditingController(),onChanged: (v) => setState(),Medium,
|
||||
37,Forms,Validate on submit,Form validation flow,_formKey.currentState!.validate(),Skip validation,if (_formKey.currentState!.validate()),Submit without validation,High,
|
||||
38,Forms,Dispose controllers,Clean up text controllers,dispose() for controllers,Memory leaks,controller.dispose() in dispose,No controller disposal,High,
|
||||
39,Performance,Use const widgets,Reduce rebuilds,const for static widgets,No const for literals,const Icon(Icons.add),Icon(Icons.add),High,
|
||||
40,Performance,Avoid rebuilding entire tree,Minimal rebuild scope,Isolate changing widgets,setState on parent,Consumer only around changing widget,setState on root widget,High,
|
||||
41,Performance,Use RepaintBoundary,Isolate repaints,RepaintBoundary for animations,Full screen repaints,RepaintBoundary(child: AnimatedWidget()),Animation without boundary,Medium,https://api.flutter.dev/flutter/widgets/RepaintBoundary-class.html
|
||||
42,Performance,Profile with DevTools,Measure before optimizing,Flutter DevTools profiling,Guess at performance,DevTools performance tab,Optimize without measuring,Medium,https://docs.flutter.dev/tools/devtools
|
||||
43,Accessibility,Use Semantics widget,Screen reader support,Semantics for accessibility,Missing accessibility info,Semantics(label: 'Submit button'),GestureDetector without semantics,High,https://api.flutter.dev/flutter/widgets/Semantics-class.html
|
||||
44,Accessibility,Support large fonts,MediaQuery text scaling,MediaQuery.textScaleFactor,Fixed font sizes,style: Theme.of(context).textTheme,TextStyle(fontSize: 14),High,
|
||||
45,Accessibility,Test with screen readers,TalkBack and VoiceOver,Test accessibility regularly,Skip accessibility testing,Regular TalkBack testing,No screen reader testing,High,
|
||||
46,Testing,Use widget tests,Test widget behavior,WidgetTester for UI tests,Unit tests only,testWidgets('...' (tester) async {}),Only test() for UI,Medium,https://docs.flutter.dev/testing
|
||||
47,Testing,Use integration tests,Full app testing,integration_test package,Manual testing only,IntegrationTestWidgetsFlutterBinding,Manual E2E testing,Medium,
|
||||
48,Testing,Mock dependencies,Isolate tests,Mockito or mocktail,Real dependencies in tests,when(mock.method()).thenReturn(),Real API calls in tests,Medium,
|
||||
49,Platform,Use Platform checks,Platform-specific code,Platform.isIOS Platform.isAndroid,Same code for all platforms,if (Platform.isIOS) {},Hardcoded iOS behavior,Medium,
|
||||
50,Platform,Use kIsWeb for web,Web platform detection,kIsWeb for web checks,Platform for web,if (kIsWeb) {},Platform.isWeb (doesn't exist),Medium,
|
||||
51,Packages,Use pub.dev packages,Community packages,Popular maintained packages,Custom implementations,cached_network_image,Custom image cache,Medium,https://pub.dev/
|
||||
52,Packages,Check package quality,Quality before adding,Pub points and popularity,Any package without review,100+ pub points,Unmaintained packages,Medium,
|
||||
|
@@ -1,51 +0,0 @@
|
||||
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
|
||||
1,Installation,Add Nuxt UI module,Install and configure Nuxt UI in your Nuxt project,pnpm add @nuxt/ui and add to modules,Manual component imports,"modules: ['@nuxt/ui']","import { UButton } from '@nuxt/ui'",High,https://ui.nuxt.com/docs/getting-started/installation/nuxt
|
||||
2,Installation,Import Tailwind and Nuxt UI CSS,Required CSS imports in main.css file,@import tailwindcss and @import @nuxt/ui,Skip CSS imports,"@import ""tailwindcss""; @import ""@nuxt/ui"";",No CSS imports,High,https://ui.nuxt.com/docs/getting-started/installation/nuxt
|
||||
3,Installation,Wrap app with UApp component,UApp provides global configs for Toast Tooltip and overlays,<UApp> wrapper in app.vue,Skip UApp wrapper,<UApp><NuxtPage/></UApp>,<NuxtPage/> without wrapper,High,https://ui.nuxt.com/docs/components/app
|
||||
4,Components,Use U prefix for components,All Nuxt UI components use U prefix by default,UButton UInput UModal,Button Input Modal,<UButton>Click</UButton>,<Button>Click</Button>,Medium,https://ui.nuxt.com/docs/getting-started/installation/nuxt
|
||||
5,Components,Use semantic color props,Use semantic colors like primary secondary error,color="primary" color="error",Hardcoded colors,"<UButton color=""primary"">","<UButton class=""bg-green-500"">",Medium,https://ui.nuxt.com/docs/getting-started/theme/design-system
|
||||
6,Components,Use variant prop for styling,Nuxt UI provides solid outline soft subtle ghost link variants,variant="soft" variant="outline",Custom button classes,"<UButton variant=""soft"">","<UButton class=""border bg-transparent"">",Medium,https://ui.nuxt.com/docs/components/button
|
||||
7,Components,Use size prop consistently,Components support xs sm md lg xl sizes,size="sm" size="lg",Arbitrary sizing classes,"<UButton size=""lg"">","<UButton class=""text-xl px-6"">",Low,https://ui.nuxt.com/docs/components/button
|
||||
8,Icons,Use icon prop with Iconify format,Nuxt UI supports Iconify icons via icon prop,icon="lucide:home" icon="heroicons:user",i-lucide-home format,"<UButton icon=""lucide:home"">","<UButton icon=""i-lucide-home"">",Medium,https://ui.nuxt.com/docs/getting-started/integrations/icons/nuxt
|
||||
9,Icons,Use leadingIcon and trailingIcon,Position icons with dedicated props for clarity,leadingIcon="lucide:plus" trailingIcon="lucide:arrow-right",Manual icon positioning,"<UButton leadingIcon=""lucide:plus"">","<UButton><Icon name=""lucide:plus""/>Add</UButton>",Low,https://ui.nuxt.com/docs/components/button
|
||||
10,Theming,Configure colors in app.config.ts,Runtime color configuration without restart,ui.colors.primary in app.config.ts,Hardcoded colors in components,"defineAppConfig({ ui: { colors: { primary: 'blue' } } })","<UButton class=""bg-blue-500"">",High,https://ui.nuxt.com/docs/getting-started/theme/design-system
|
||||
11,Theming,Use @theme directive for custom colors,Define design tokens in CSS with Tailwind @theme,@theme { --color-brand-500: #xxx },Inline color definitions,@theme { --color-brand-500: #ef4444; },:style="{ color: '#ef4444' }",Medium,https://ui.nuxt.com/docs/getting-started/theme/design-system
|
||||
12,Theming,Extend semantic colors in nuxt.config,Register new colors like tertiary in theme.colors,theme.colors array in ui config,Use undefined colors,"ui: { theme: { colors: ['primary', 'tertiary'] } }","<UButton color=""tertiary""> without config",Medium,https://ui.nuxt.com/docs/getting-started/theme/design-system
|
||||
13,Forms,Use UForm with schema validation,UForm supports Zod Yup Joi Valibot schemas,:schema prop with validation schema,Manual form validation,"<UForm :schema=""schema"" :state=""state"">",Manual @blur validation,High,https://ui.nuxt.com/docs/components/form
|
||||
14,Forms,Use UFormField for field wrapper,Provides label error message and validation display,UFormField with name prop,Manual error handling,"<UFormField name=""email"" label=""Email"">",<div><label>Email</label><UInput/><span>error</span></div>,Medium,https://ui.nuxt.com/docs/components/form-field
|
||||
15,Forms,Handle form submit with @submit,UForm emits submit event with validated data,@submit handler on UForm,@click on submit button,"<UForm @submit=""onSubmit"">","<UButton @click=""onSubmit"">",Medium,https://ui.nuxt.com/docs/components/form
|
||||
16,Forms,Use validateOn prop for validation timing,Control when validation triggers (blur change input),validateOn="['blur']" for performance,Always validate on input,"<UForm :validateOn=""['blur', 'change']"">","<UForm> (validates on every keystroke)",Low,https://ui.nuxt.com/docs/components/form
|
||||
17,Overlays,Use v-model:open for overlay control,Modal Slideover Drawer use v-model:open,v-model:open for controlled state,Manual show/hide logic,"<UModal v-model:open=""isOpen"">",<UModal v-if="isOpen">,Medium,https://ui.nuxt.com/docs/components/modal
|
||||
18,Overlays,Use useOverlay composable for programmatic overlays,Open overlays programmatically without template refs,useOverlay().open(MyModal),Template ref and manual control,"const overlay = useOverlay(); overlay.open(MyModal, { props })","const modal = ref(); modal.value.open()",Medium,https://ui.nuxt.com/docs/components/modal
|
||||
19,Overlays,Use title and description props,Built-in header support for overlays,title="Confirm" description="Are you sure?",Manual header content,"<UModal title=""Confirm"" description=""Are you sure?"">","<UModal><template #header><h2>Confirm</h2></template>",Low,https://ui.nuxt.com/docs/components/modal
|
||||
20,Dashboard,Use UDashboardSidebar for navigation,Provides collapsible resizable sidebar with mobile support,UDashboardSidebar with header default footer slots,Custom sidebar implementation,<UDashboardSidebar><template #header>...</template></UDashboardSidebar>,<aside class="w-64 border-r">,Medium,https://ui.nuxt.com/docs/components/dashboard-sidebar
|
||||
21,Dashboard,Use UDashboardGroup for layout,Wraps dashboard components with sidebar state management,UDashboardGroup > UDashboardSidebar + UDashboardPanel,Manual layout flex containers,<UDashboardGroup><UDashboardSidebar/><UDashboardPanel/></UDashboardGroup>,"<div class=""flex""><aside/><main/></div>",Medium,https://ui.nuxt.com/docs/components/dashboard-group
|
||||
22,Dashboard,Use UDashboardNavbar for top navigation,Responsive navbar with mobile menu support,UDashboardNavbar in dashboard layout,Custom navbar implementation,<UDashboardNavbar :links="navLinks"/>,<nav class="border-b">,Low,https://ui.nuxt.com/docs/components/dashboard-navbar
|
||||
23,Tables,Use UTable with data and columns props,Powered by TanStack Table with built-in features,:data and :columns props,Manual table markup,"<UTable :data=""users"" :columns=""columns""/>","<table><tr v-for=""user in users"">",High,https://ui.nuxt.com/docs/components/table
|
||||
24,Tables,Define columns with accessorKey,Column definitions use accessorKey for data binding,accessorKey: 'email' in column def,String column names only,"{ accessorKey: 'email', header: 'Email' }","['name', 'email']",Medium,https://ui.nuxt.com/docs/components/table
|
||||
25,Tables,Use cell slot for custom rendering,Customize cell content with scoped slots,#cell-columnName slot,Override entire table,<template #cell-status="{ row }">,Manual column render function,Medium,https://ui.nuxt.com/docs/components/table
|
||||
26,Tables,Enable sorting with sortable column option,Add sortable: true to column definition,sortable: true in column,Manual sort implementation,"{ accessorKey: 'name', sortable: true }",@click="sortBy('name')",Low,https://ui.nuxt.com/docs/components/table
|
||||
27,Navigation,Use UNavigationMenu for nav links,Horizontal or vertical navigation with dropdown support,UNavigationMenu with items array,Manual nav with v-for,"<UNavigationMenu :items=""navItems""/>","<nav><a v-for=""item in items"">",Medium,https://ui.nuxt.com/docs/components/navigation-menu
|
||||
28,Navigation,Use UBreadcrumb for page hierarchy,Automatic breadcrumb with NuxtLink support,:items array with label and to,Manual breadcrumb links,"<UBreadcrumb :items=""breadcrumbs""/>","<nav><span v-for=""crumb in crumbs"">",Low,https://ui.nuxt.com/docs/components/breadcrumb
|
||||
29,Navigation,Use UTabs for tabbed content,Tab navigation with content panels,UTabs with items containing slot content,Manual tab state,"<UTabs :items=""tabs""/>","<div><button @click=""tab=1"">",Medium,https://ui.nuxt.com/docs/components/tabs
|
||||
30,Feedback,Use useToast for notifications,Composable for toast notifications,useToast().add({ title description }),Alert components for toasts,"const toast = useToast(); toast.add({ title: 'Saved' })",<UAlert v-if="showSuccess">,High,https://ui.nuxt.com/docs/components/toast
|
||||
31,Feedback,Use UAlert for inline messages,Static alert messages with icon and actions,UAlert with title description color,Toast for static messages,"<UAlert title=""Warning"" color=""warning""/>",useToast for inline alerts,Medium,https://ui.nuxt.com/docs/components/alert
|
||||
32,Feedback,Use USkeleton for loading states,Placeholder content during data loading,USkeleton with appropriate size,Spinner for content loading,<USkeleton class="h-4 w-32"/>,<UIcon name="lucide:loader" class="animate-spin"/>,Low,https://ui.nuxt.com/docs/components/skeleton
|
||||
33,Color Mode,Use UColorModeButton for theme toggle,Built-in light/dark mode toggle button,UColorModeButton component,Manual color mode logic,<UColorModeButton/>,"<button @click=""toggleColorMode"">",Low,https://ui.nuxt.com/docs/components/color-mode-button
|
||||
34,Color Mode,Use UColorModeSelect for theme picker,Dropdown to select system light or dark mode,UColorModeSelect component,Custom select for theme,<UColorModeSelect/>,"<USelect v-model=""colorMode"" :items=""modes""/>",Low,https://ui.nuxt.com/docs/components/color-mode-select
|
||||
35,Customization,Use ui prop for component styling,Override component styles via ui prop,ui prop with slot class overrides,Global CSS overrides,"<UButton :ui=""{ base: 'rounded-full' }""/>",<UButton class="!rounded-full"/>,Medium,https://ui.nuxt.com/docs/getting-started/theme/components
|
||||
36,Customization,Configure default variants in nuxt.config,Set default color and size for all components,theme.defaultVariants in ui config,Repeat props on every component,"ui: { theme: { defaultVariants: { color: 'neutral' } } }","<UButton color=""neutral""> everywhere",Medium,https://ui.nuxt.com/docs/getting-started/installation/nuxt
|
||||
37,Customization,Use app.config.ts for theme overrides,Runtime theme customization,defineAppConfig with ui key,nuxt.config for runtime values,"defineAppConfig({ ui: { button: { defaultVariants: { size: 'sm' } } } })","nuxt.config ui.button.size: 'sm'",Medium,https://ui.nuxt.com/docs/getting-started/theme/components
|
||||
38,Performance,Enable component detection,Tree-shake unused component CSS,experimental.componentDetection: true,Include all component CSS,"ui: { experimental: { componentDetection: true } }","ui: {} (includes all CSS)",Low,https://ui.nuxt.com/docs/getting-started/installation/nuxt
|
||||
39,Performance,Use UTable virtualize for large data,Enable virtualization for 1000+ rows,:virtualize prop on UTable,Render all rows,"<UTable :data=""largeData"" virtualize/>","<UTable :data=""largeData""/>",Medium,https://ui.nuxt.com/docs/components/table
|
||||
40,Accessibility,Use semantic component props,Components have built-in ARIA support,Use title description label props,Skip accessibility props,"<UModal title=""Settings"">","<UModal><h2>Settings</h2>",Medium,https://ui.nuxt.com/docs/components/modal
|
||||
41,Accessibility,Use UFormField for form accessibility,Automatic label-input association,UFormField wraps inputs,Manual id and for attributes,"<UFormField label=""Email""><UInput/></UFormField>","<label for=""email"">Email</label><UInput id=""email""/>",High,https://ui.nuxt.com/docs/components/form-field
|
||||
42,Content,Use UContentToc for table of contents,Automatic TOC with active heading highlight,UContentToc with :links,Manual TOC implementation,"<UContentToc :links=""toc""/>","<nav><a v-for=""heading in headings"">",Low,https://ui.nuxt.com/docs/components/content-toc
|
||||
43,Content,Use UContentSearch for docs search,Command palette for documentation search,UContentSearch with Nuxt Content,Custom search implementation,<UContentSearch/>,<UCommandPalette :groups="searchResults"/>,Low,https://ui.nuxt.com/docs/components/content-search
|
||||
44,AI/Chat,Use UChatMessages for chat UI,Designed for Vercel AI SDK integration,UChatMessages with messages array,Custom chat message list,"<UChatMessages :messages=""messages""/>","<div v-for=""msg in messages"">",Medium,https://ui.nuxt.com/docs/components/chat-messages
|
||||
45,AI/Chat,Use UChatPrompt for input,Enhanced textarea for AI prompts,UChatPrompt with v-model,Basic textarea,<UChatPrompt v-model="prompt"/>,<UTextarea v-model="prompt"/>,Medium,https://ui.nuxt.com/docs/components/chat-prompt
|
||||
46,Editor,Use UEditor for rich text,TipTap-based editor with toolbar support,UEditor with v-model:content,Custom TipTap setup,"<UEditor v-model:content=""content""/>",Manual TipTap initialization,Medium,https://ui.nuxt.com/docs/components/editor
|
||||
47,Links,Use to prop for navigation,UButton and ULink support NuxtLink to prop,to="/dashboard" for internal links,href for internal navigation,"<UButton to=""/dashboard"">","<UButton href=""/dashboard"">",Medium,https://ui.nuxt.com/docs/components/button
|
||||
48,Links,Use external prop for outside links,Explicitly mark external links,target="_blank" with external URLs,Forget rel="noopener","<UButton to=""https://example.com"" target=""_blank"">","<UButton href=""https://..."">",Low,https://ui.nuxt.com/docs/components/link
|
||||
49,Loading,Use loadingAuto on buttons,Automatic loading state from @click promise,loadingAuto prop on UButton,Manual loading state,"<UButton loadingAuto @click=""async () => await save()"">","<UButton :loading=""isLoading"" @click=""save"">",Low,https://ui.nuxt.com/docs/components/button
|
||||
50,Loading,Use UForm loadingAuto,Auto-disable form during submit,loadingAuto on UForm (default true),Manual form disabled state,"<UForm @submit=""handleSubmit"">","<UForm :disabled=""isSubmitting"">",Low,https://ui.nuxt.com/docs/components/form
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 94.
|
@@ -1,59 +0,0 @@
|
||||
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
|
||||
1,Routing,Use file-based routing,Create routes by adding files in pages directory,pages/ directory with index.vue,Manual route configuration,pages/dashboard/index.vue,Custom router setup,Medium,https://nuxt.com/docs/getting-started/routing
|
||||
2,Routing,Use dynamic route parameters,Create dynamic routes with bracket syntax,[id].vue for dynamic params,Hardcoded routes for dynamic content,pages/posts/[id].vue,pages/posts/post1.vue,Medium,https://nuxt.com/docs/getting-started/routing
|
||||
3,Routing,Use catch-all routes,Handle multiple path segments with [...slug],[...slug].vue for catch-all,Multiple nested dynamic routes,pages/[...slug].vue,pages/[a]/[b]/[c].vue,Low,https://nuxt.com/docs/getting-started/routing
|
||||
4,Routing,Define page metadata with definePageMeta,Set page-level configuration and middleware,definePageMeta for layout middleware title,Manual route meta configuration,"definePageMeta({ layout: 'admin', middleware: 'auth' })",router.beforeEach for page config,High,https://nuxt.com/docs/api/utils/define-page-meta
|
||||
5,Routing,Use validate for route params,Validate dynamic route parameters before rendering,validate function in definePageMeta,Manual validation in setup,"definePageMeta({ validate: (route) => /^\d+$/.test(route.params.id) })",if (!valid) navigateTo('/404'),Medium,https://nuxt.com/docs/api/utils/define-page-meta
|
||||
6,Rendering,Use SSR by default,Server-side rendering is enabled by default,Keep ssr: true (default),Disable SSR unnecessarily,ssr: true (default),ssr: false for all pages,High,https://nuxt.com/docs/guide/concepts/rendering
|
||||
7,Rendering,Use .client suffix for client-only components,Mark components to render only on client,ComponentName.client.vue suffix,v-if with process.client check,Comments.client.vue,<div v-if="process.client"><Comments/></div>,Medium,https://nuxt.com/docs/guide/directory-structure/components
|
||||
8,Rendering,Use .server suffix for server-only components,Mark components to render only on server,ComponentName.server.vue suffix,Manual server check,HeavyMarkdown.server.vue,v-if="process.server",Low,https://nuxt.com/docs/guide/directory-structure/components
|
||||
9,DataFetching,Use useFetch for simple data fetching,Wrapper around useAsyncData for URL fetching,useFetch for API calls,$fetch in onMounted,"const { data } = await useFetch('/api/posts')","onMounted(async () => { data.value = await $fetch('/api/posts') })",High,https://nuxt.com/docs/api/composables/use-fetch
|
||||
10,DataFetching,Use useAsyncData for complex fetching,Fine-grained control over async data,useAsyncData for CMS or custom fetching,useFetch for non-URL data sources,"const { data } = await useAsyncData('posts', () => cms.getPosts())","const { data } = await useFetch(() => cms.getPosts())",Medium,https://nuxt.com/docs/api/composables/use-async-data
|
||||
11,DataFetching,Use $fetch for non-reactive requests,$fetch for event handlers and non-component code,$fetch in event handlers or server routes,useFetch in click handlers,"async function submit() { await $fetch('/api/submit', { method: 'POST' }) }","async function submit() { await useFetch('/api/submit') }",High,https://nuxt.com/docs/api/utils/dollarfetch
|
||||
12,DataFetching,Use lazy option for non-blocking fetch,Defer data fetching for better initial load,lazy: true for below-fold content,Blocking fetch for non-critical data,"useFetch('/api/comments', { lazy: true })",await useFetch('/api/comments') for footer,Medium,https://nuxt.com/docs/api/composables/use-fetch
|
||||
13,DataFetching,Use server option to control fetch location,Choose where data is fetched,server: false for client-only data,Server fetch for user-specific client data,"useFetch('/api/user-preferences', { server: false })",useFetch for localStorage-dependent data,Medium,https://nuxt.com/docs/api/composables/use-fetch
|
||||
14,DataFetching,Use pick to reduce payload size,Select only needed fields from response,pick option for large responses,Fetching entire objects when few fields needed,"useFetch('/api/user', { pick: ['id', 'name'] })",useFetch('/api/user') then destructure,Low,https://nuxt.com/docs/api/composables/use-fetch
|
||||
15,DataFetching,Use transform for data manipulation,Transform data before storing in state,transform option for data shaping,Manual transformation after fetch,"useFetch('/api/posts', { transform: (posts) => posts.map(p => p.title) })",const titles = data.value.map(p => p.title),Low,https://nuxt.com/docs/api/composables/use-fetch
|
||||
16,DataFetching,Handle loading and error states,Always handle pending and error states,Check status pending error refs,Ignoring loading states,"<div v-if=""status === 'pending'"">Loading...</div>",No loading indicator,High,https://nuxt.com/docs/getting-started/data-fetching
|
||||
17,Lifecycle,Avoid side effects in script setup root,Move side effects to lifecycle hooks,Side effects in onMounted,setInterval in root script setup,"onMounted(() => { interval = setInterval(...) })","<script setup>setInterval(...)</script>",High,https://nuxt.com/docs/guide/concepts/nuxt-lifecycle
|
||||
18,Lifecycle,Use onMounted for DOM access,Access DOM only after component is mounted,onMounted for DOM manipulation,Direct DOM access in setup,"onMounted(() => { document.getElementById('el') })","<script setup>document.getElementById('el')</script>",High,https://nuxt.com/docs/api/composables/on-mounted
|
||||
19,Lifecycle,Use nextTick for post-render access,Wait for DOM updates before accessing elements,await nextTick() after state changes,Immediate DOM access after state change,"count.value++; await nextTick(); el.value.focus()","count.value++; el.value.focus()",Medium,https://nuxt.com/docs/api/utils/next-tick
|
||||
20,Lifecycle,Use onPrehydrate for pre-hydration logic,Run code before Nuxt hydrates the page,onPrehydrate for client setup,onMounted for hydration-critical code,"onPrehydrate(() => { console.log(window) })",onMounted for pre-hydration needs,Low,https://nuxt.com/docs/api/composables/on-prehydrate
|
||||
21,Server,Use server/api for API routes,Create API endpoints in server/api directory,server/api/users.ts for /api/users,Manual Express setup,server/api/hello.ts -> /api/hello,app.get('/api/hello'),High,https://nuxt.com/docs/guide/directory-structure/server
|
||||
22,Server,Use defineEventHandler for handlers,Define server route handlers,defineEventHandler for all handlers,export default function,"export default defineEventHandler((event) => { return { hello: 'world' } })","export default function(req, res) {}",High,https://nuxt.com/docs/guide/directory-structure/server
|
||||
23,Server,Use server/routes for non-api routes,Routes without /api prefix,server/routes for custom paths,server/api for non-api routes,server/routes/sitemap.xml.ts,server/api/sitemap.xml.ts,Medium,https://nuxt.com/docs/guide/directory-structure/server
|
||||
24,Server,Use getQuery and readBody for input,Access query params and request body,getQuery(event) readBody(event),Direct event access,"const { id } = getQuery(event)",event.node.req.query,Medium,https://nuxt.com/docs/guide/directory-structure/server
|
||||
25,Server,Validate server input,Always validate input in server handlers,Zod or similar for validation,Trust client input,"const body = await readBody(event); schema.parse(body)",const body = await readBody(event),High,https://nuxt.com/docs/guide/directory-structure/server
|
||||
26,State,Use useState for shared reactive state,SSR-friendly shared state across components,useState for cross-component state,ref for shared state,"const count = useState('count', () => 0)",const count = ref(0) in composable,High,https://nuxt.com/docs/api/composables/use-state
|
||||
27,State,Use unique keys for useState,Prevent state conflicts with unique keys,Descriptive unique keys for each state,Generic or duplicate keys,"useState('user-preferences', () => ({}))",useState('data') in multiple places,Medium,https://nuxt.com/docs/api/composables/use-state
|
||||
28,State,Use Pinia for complex state,Pinia for advanced state management,@pinia/nuxt for complex apps,Custom state management,useMainStore() with Pinia,Custom reactive store implementation,Medium,https://nuxt.com/docs/getting-started/state-management
|
||||
29,State,Use callOnce for one-time async operations,Ensure async operations run only once,callOnce for store initialization,Direct await in component,"await callOnce(store.fetch)",await store.fetch() on every render,Medium,https://nuxt.com/docs/api/utils/call-once
|
||||
30,SEO,Use useSeoMeta for SEO tags,Type-safe SEO meta tag management,useSeoMeta for meta tags,useHead for simple meta,"useSeoMeta({ title: 'Home', ogTitle: 'Home', description: '...' })","useHead({ meta: [{ name: 'description', content: '...' }] })",High,https://nuxt.com/docs/api/composables/use-seo-meta
|
||||
31,SEO,Use reactive values in useSeoMeta,Dynamic SEO tags with refs or getters,Computed getters for dynamic values,Static values for dynamic content,"useSeoMeta({ title: () => post.value.title })","useSeoMeta({ title: post.value.title })",Medium,https://nuxt.com/docs/api/composables/use-seo-meta
|
||||
32,SEO,Use useHead for non-meta head elements,Scripts styles links in head,useHead for scripts and links,useSeoMeta for scripts,"useHead({ script: [{ src: '/analytics.js' }] })","useSeoMeta({ script: '...' })",Medium,https://nuxt.com/docs/api/composables/use-head
|
||||
33,SEO,Include OpenGraph tags,Add OG tags for social sharing,ogTitle ogDescription ogImage,Missing social preview,"useSeoMeta({ ogImage: '/og.png', twitterCard: 'summary_large_image' })",No OG configuration,Medium,https://nuxt.com/docs/api/composables/use-seo-meta
|
||||
34,Middleware,Use defineNuxtRouteMiddleware,Define route middleware properly,defineNuxtRouteMiddleware wrapper,export default function,"export default defineNuxtRouteMiddleware((to, from) => {})","export default function(to, from) {}",High,https://nuxt.com/docs/guide/directory-structure/middleware
|
||||
35,Middleware,Use navigateTo for redirects,Redirect in middleware with navigateTo,return navigateTo('/login'),router.push in middleware,"if (!auth) return navigateTo('/login')","if (!auth) router.push('/login')",High,https://nuxt.com/docs/api/utils/navigate-to
|
||||
36,Middleware,Reference middleware in definePageMeta,Apply middleware to specific pages,middleware array in definePageMeta,Global middleware for page-specific,definePageMeta({ middleware: ['auth'] }),Global auth check for one page,Medium,https://nuxt.com/docs/guide/directory-structure/middleware
|
||||
37,Middleware,Use .global suffix for global middleware,Apply middleware to all routes,auth.global.ts for app-wide auth,Manual middleware on every page,middleware/auth.global.ts,middleware: ['auth'] on every page,Medium,https://nuxt.com/docs/guide/directory-structure/middleware
|
||||
38,ErrorHandling,Use createError for errors,Create errors with proper status codes,createError with statusCode,throw new Error,"throw createError({ statusCode: 404, statusMessage: 'Not Found' })",throw new Error('Not Found'),High,https://nuxt.com/docs/api/utils/create-error
|
||||
39,ErrorHandling,Use NuxtErrorBoundary for local errors,Handle errors within component subtree,NuxtErrorBoundary for component errors,Global error page for local errors,"<NuxtErrorBoundary @error=""log""><template #error=""{ error }"">",error.vue for component errors,Medium,https://nuxt.com/docs/getting-started/error-handling
|
||||
40,ErrorHandling,Use clearError to recover from errors,Clear error state and optionally redirect,clearError({ redirect: '/' }),Manual error state reset,clearError({ redirect: '/home' }),error.value = null,Medium,https://nuxt.com/docs/api/utils/clear-error
|
||||
41,ErrorHandling,Use short statusMessage,Keep statusMessage brief for security,Short generic messages,Detailed error info in statusMessage,"createError({ statusCode: 400, statusMessage: 'Bad Request' })","createError({ statusMessage: 'Invalid user ID: 123' })",High,https://nuxt.com/docs/getting-started/error-handling
|
||||
42,Link,Use NuxtLink for internal navigation,Client-side navigation with prefetching,<NuxtLink to> for internal links,<a href> for internal links,<NuxtLink to="/about">About</NuxtLink>,<a href="/about">About</a>,High,https://nuxt.com/docs/api/components/nuxt-link
|
||||
43,Link,Configure prefetch behavior,Control when prefetching occurs,prefetchOn for interaction-based,Default prefetch for low-priority,"<NuxtLink prefetch-on=""interaction"">",Always default prefetch,Low,https://nuxt.com/docs/api/components/nuxt-link
|
||||
44,Link,Use useRouter for programmatic navigation,Navigate programmatically,useRouter().push() for navigation,Direct window.location,"const router = useRouter(); router.push('/dashboard')",window.location.href = '/dashboard',Medium,https://nuxt.com/docs/api/composables/use-router
|
||||
45,Link,Use navigateTo in composables,Navigate outside components,navigateTo() in middleware or plugins,useRouter in non-component code,return navigateTo('/login'),router.push in middleware,Medium,https://nuxt.com/docs/api/utils/navigate-to
|
||||
46,AutoImports,Leverage auto-imports,Use auto-imported composables directly,Direct use of ref computed useFetch,Manual imports for Nuxt composables,"const count = ref(0)","import { ref } from 'vue'; const count = ref(0)",Medium,https://nuxt.com/docs/guide/concepts/auto-imports
|
||||
47,AutoImports,Use #imports for explicit imports,Explicit imports when needed,#imports for clarity or disabled auto-imports,"import from 'vue' when auto-import enabled","import { ref } from '#imports'","import { ref } from 'vue'",Low,https://nuxt.com/docs/guide/concepts/auto-imports
|
||||
48,AutoImports,Configure third-party auto-imports,Add external package auto-imports,imports.presets in nuxt.config,Manual imports everywhere,"imports: { presets: [{ from: 'vue-i18n', imports: ['useI18n'] }] }",import { useI18n } everywhere,Low,https://nuxt.com/docs/guide/concepts/auto-imports
|
||||
49,Plugins,Use defineNuxtPlugin,Define plugins properly,defineNuxtPlugin wrapper,export default function,"export default defineNuxtPlugin((nuxtApp) => {})","export default function(ctx) {}",High,https://nuxt.com/docs/guide/directory-structure/plugins
|
||||
50,Plugins,Use provide for injection,Provide helpers across app,return { provide: {} } for type safety,nuxtApp.provide without types,"return { provide: { hello: (name) => `Hello ${name}!` } }","nuxtApp.provide('hello', fn)",Medium,https://nuxt.com/docs/guide/directory-structure/plugins
|
||||
51,Plugins,Use .client or .server suffix,Control plugin execution environment,plugin.client.ts for client-only,if (process.client) checks,analytics.client.ts,"if (process.client) { // analytics }",Medium,https://nuxt.com/docs/guide/directory-structure/plugins
|
||||
52,Environment,Use runtimeConfig for env vars,Access environment variables safely,runtimeConfig in nuxt.config,process.env directly,"runtimeConfig: { apiSecret: '', public: { apiBase: '' } }",process.env.API_SECRET in components,High,https://nuxt.com/docs/guide/going-further/runtime-config
|
||||
53,Environment,Use NUXT_ prefix for env override,Override config with environment variables,NUXT_API_SECRET NUXT_PUBLIC_API_BASE,Custom env var names,NUXT_PUBLIC_API_BASE=https://api.example.com,API_BASE=https://api.example.com,High,https://nuxt.com/docs/guide/going-further/runtime-config
|
||||
54,Environment,Access public config with useRuntimeConfig,Get public config in components,useRuntimeConfig().public,Direct process.env access,const config = useRuntimeConfig(); config.public.apiBase,process.env.NUXT_PUBLIC_API_BASE,High,https://nuxt.com/docs/api/composables/use-runtime-config
|
||||
55,Environment,Keep secrets in private config,Server-only secrets in runtimeConfig root,runtimeConfig.apiSecret (server only),Secrets in public config,runtimeConfig: { dbPassword: '' },runtimeConfig: { public: { dbPassword: '' } },High,https://nuxt.com/docs/guide/going-further/runtime-config
|
||||
56,Performance,Use Lazy prefix for code splitting,Lazy load components with Lazy prefix,<LazyComponent> for below-fold,Eager load all components,<LazyMountainsList v-if="show"/>,<MountainsList/> for hidden content,Medium,https://nuxt.com/docs/guide/directory-structure/components
|
||||
57,Performance,Use useLazyFetch for non-blocking data,Alias for useFetch with lazy: true,useLazyFetch for secondary data,useFetch for all requests,"const { data } = useLazyFetch('/api/comments')",await useFetch for comments section,Medium,https://nuxt.com/docs/api/composables/use-lazy-fetch
|
||||
58,Performance,Use lazy hydration for interactivity,Delay component hydration until needed,LazyComponent with hydration strategy,Immediate hydration for all,<LazyModal hydrate-on-visible/>,<Modal/> in footer,Low,https://nuxt.com/docs/guide/going-further/experimental-features
|
||||
|
Can't render this file because it contains an unexpected character in line 8 and column 193.
|
@@ -1,52 +0,0 @@
|
||||
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
|
||||
1,Components,Use functional components,Hooks-based components are standard,Functional components with hooks,Class components,const App = () => { },class App extends Component,Medium,https://reactnative.dev/docs/intro-react
|
||||
2,Components,Keep components small,Single responsibility principle,Split into smaller components,Large monolithic components,<Header /><Content /><Footer />,500+ line component,Medium,
|
||||
3,Components,Use TypeScript,Type safety for props and state,TypeScript for new projects,JavaScript without types,const Button: FC<Props> = () => { },const Button = (props) => { },Medium,
|
||||
4,Components,Colocate component files,Keep related files together,Component folder with styles,Flat structure,components/Button/index.tsx styles.ts,components/Button.tsx styles/button.ts,Low,
|
||||
5,Styling,Use StyleSheet.create,Optimized style objects,StyleSheet for all styles,Inline style objects,StyleSheet.create({ container: {} }),style={{ margin: 10 }},High,https://reactnative.dev/docs/stylesheet
|
||||
6,Styling,Avoid inline styles,Prevent object recreation,Styles in StyleSheet,Inline style objects in render,style={styles.container},"style={{ margin: 10, padding: 5 }}",Medium,
|
||||
7,Styling,Use flexbox for layout,React Native uses flexbox,flexDirection alignItems justifyContent,Absolute positioning everywhere,flexDirection: 'row',position: 'absolute' everywhere,Medium,https://reactnative.dev/docs/flexbox
|
||||
8,Styling,Handle platform differences,Platform-specific styles,Platform.select or .ios/.android files,Same styles for both platforms,"Platform.select({ ios: {}, android: {} })",Hardcoded iOS values,Medium,https://reactnative.dev/docs/platform-specific-code
|
||||
9,Styling,Use responsive dimensions,Scale for different screens,Dimensions or useWindowDimensions,Fixed pixel values,useWindowDimensions(),width: 375,Medium,
|
||||
10,Navigation,Use React Navigation,Standard navigation library,React Navigation for routing,Manual navigation management,createStackNavigator(),Custom navigation state,Medium,https://reactnavigation.org/
|
||||
11,Navigation,Type navigation params,Type-safe navigation,Typed navigation props,Untyped navigation,"navigation.navigate<RootStackParamList>('Home', { id })","navigation.navigate('Home', { id })",Medium,
|
||||
12,Navigation,Use deep linking,Support URL-based navigation,Configure linking prop,No deep link support,linking: { prefixes: [] },No linking configuration,Medium,https://reactnavigation.org/docs/deep-linking/
|
||||
13,Navigation,Handle back button,Android back button handling,useFocusEffect with BackHandler,Ignore back button,BackHandler.addEventListener,No back handler,High,
|
||||
14,State,Use useState for local state,Simple component state,useState for UI state,Class component state,"const [count, setCount] = useState(0)",this.state = { count: 0 },Medium,
|
||||
15,State,Use useReducer for complex state,Complex state logic,useReducer for related state,Multiple useState for related values,useReducer(reducer initialState),5+ useState calls,Medium,
|
||||
16,State,Use context sparingly,Context for global state,Context for theme auth locale,Context for frequently changing data,ThemeContext for app theme,Context for list item data,Medium,
|
||||
17,State,Consider Zustand or Redux,External state management,Zustand for simple Redux for complex,useState for global state,create((set) => ({ })),Prop drilling global state,Medium,
|
||||
18,Lists,Use FlatList for long lists,Virtualized list rendering,FlatList for 50+ items,ScrollView with map,<FlatList data={items} />,<ScrollView>{items.map()}</ScrollView>,High,https://reactnative.dev/docs/flatlist
|
||||
19,Lists,Provide keyExtractor,Unique keys for list items,keyExtractor with stable ID,Index as key,keyExtractor={(item) => item.id},"keyExtractor={(_, index) => index}",High,
|
||||
20,Lists,Optimize renderItem,Memoize list item components,React.memo for list items,Inline render function,renderItem={({ item }) => <MemoizedItem item={item} />},renderItem={({ item }) => <View>...</View>},High,
|
||||
21,Lists,Use getItemLayout for fixed height,Skip measurement for performance,getItemLayout when height known,Dynamic measurement for fixed items,"getItemLayout={(_, index) => ({ length: 50, offset: 50 * index, index })}",No getItemLayout for fixed height,Medium,
|
||||
22,Lists,Implement windowSize,Control render window,Smaller windowSize for memory,Default windowSize for large lists,windowSize={5},windowSize={21} for huge lists,Medium,
|
||||
23,Performance,Use React.memo,Prevent unnecessary re-renders,memo for pure components,No memoization,export default memo(MyComponent),export default MyComponent,Medium,
|
||||
24,Performance,Use useCallback for handlers,Stable function references,useCallback for props,New function on every render,"useCallback(() => {}, [deps])",() => handlePress(),Medium,
|
||||
25,Performance,Use useMemo for expensive ops,Cache expensive calculations,useMemo for heavy computations,Recalculate every render,"useMemo(() => expensive(), [deps])",const result = expensive(),Medium,
|
||||
26,Performance,Avoid anonymous functions in JSX,Prevent re-renders,Named handlers or useCallback,Inline arrow functions,onPress={handlePress},onPress={() => doSomething()},Medium,
|
||||
27,Performance,Use Hermes engine,Improved startup and memory,Enable Hermes in build,JavaScriptCore for new projects,hermes_enabled: true,hermes_enabled: false,Medium,https://reactnative.dev/docs/hermes
|
||||
28,Images,Use expo-image,Modern performant image component for React Native,"Use expo-image for caching, blurring, and performance",Use default Image for heavy lists or unmaintained libraries,<Image source={url} cachePolicy='memory-disk' /> (expo-image),<FastImage source={url} />,Medium,https://docs.expo.dev/versions/latest/sdk/image/
|
||||
29,Images,Specify image dimensions,Prevent layout shifts,width and height for remote images,No dimensions for network images,<Image style={{ width: 100 height: 100 }} />,<Image source={{ uri }} /> no size,High,
|
||||
30,Images,Use resizeMode,Control image scaling,resizeMode cover contain,Stretch images,"resizeMode=""cover""",No resizeMode,Low,
|
||||
31,Forms,Use controlled inputs,State-controlled form fields,value + onChangeText,Uncontrolled inputs,<TextInput value={text} onChangeText={setText} />,<TextInput defaultValue={text} />,Medium,
|
||||
32,Forms,Handle keyboard,Manage keyboard visibility,KeyboardAvoidingView,Content hidden by keyboard,"<KeyboardAvoidingView behavior=""padding"">",No keyboard handling,High,https://reactnative.dev/docs/keyboardavoidingview
|
||||
33,Forms,Use proper keyboard types,Appropriate keyboard for input,keyboardType for input type,Default keyboard for all,"keyboardType=""email-address""","keyboardType=""default"" for email",Low,
|
||||
34,Touch,Use Pressable,Modern touch handling,Pressable for touch interactions,TouchableOpacity for new code,<Pressable onPress={} />,<TouchableOpacity onPress={} />,Low,https://reactnative.dev/docs/pressable
|
||||
35,Touch,Provide touch feedback,Visual feedback on press,Ripple or opacity change,No feedback on press,android_ripple={{ color: 'gray' }},No press feedback,Medium,
|
||||
36,Touch,Set hitSlop for small targets,Increase touch area,hitSlop for icons and small buttons,Tiny touch targets,hitSlop={{ top: 10 bottom: 10 }},44x44 with no hitSlop,Medium,
|
||||
37,Animation,Use Reanimated,High-performance animations,react-native-reanimated,Animated API for complex,useSharedValue useAnimatedStyle,Animated.timing for gesture,Medium,https://docs.swmansion.com/react-native-reanimated/
|
||||
38,Animation,Run on UI thread,worklets for smooth animation,Run animations on UI thread,JS thread animations,runOnUI(() => {}),Animated on JS thread,High,
|
||||
39,Animation,Use gesture handler,Native gesture recognition,react-native-gesture-handler,JS-based gesture handling,<GestureDetector>,<View onTouchMove={} />,Medium,https://docs.swmansion.com/react-native-gesture-handler/
|
||||
40,Async,Handle loading states,Show loading indicators,ActivityIndicator during load,Empty screen during load,{isLoading ? <ActivityIndicator /> : <Content />},No loading state,Medium,
|
||||
41,Async,Handle errors gracefully,Error boundaries and fallbacks,Error UI for failed requests,Crash on error,{error ? <ErrorView /> : <Content />},No error handling,High,
|
||||
42,Async,Cancel async operations,Cleanup on unmount,AbortController or cleanup,Memory leaks from async,useEffect cleanup,No cleanup for subscriptions,High,
|
||||
43,Accessibility,Add accessibility labels,Describe UI elements,accessibilityLabel for all interactive,Missing labels,"accessibilityLabel=""Submit form""",<Pressable> without label,High,https://reactnative.dev/docs/accessibility
|
||||
44,Accessibility,Use accessibility roles,Semantic meaning,accessibilityRole for elements,Wrong roles,"accessibilityRole=""button""",No role for button,Medium,
|
||||
45,Accessibility,Support screen readers,Test with TalkBack/VoiceOver,Test with screen readers,Skip accessibility testing,Regular TalkBack testing,No screen reader testing,High,
|
||||
46,Testing,Use React Native Testing Library,Component testing,render and fireEvent,Enzyme or manual testing,render(<Component />),shallow(<Component />),Medium,https://callstack.github.io/react-native-testing-library/
|
||||
47,Testing,Test on real devices,Real device behavior,Test on iOS and Android devices,Simulator only,Device testing in CI,Simulator only testing,High,
|
||||
48,Testing,Use Detox for E2E,End-to-end testing,Detox for critical flows,Manual E2E testing,detox test,Manual testing only,Medium,https://wix.github.io/Detox/
|
||||
49,Native,Use native modules carefully,Bridge has overhead,Batch native calls,Frequent bridge crossing,Batch updates,Call native on every keystroke,High,
|
||||
50,Native,Use Expo when possible,Simplified development,Expo for standard features,Bare RN for simple apps,expo install package,react-native link package,Low,https://docs.expo.dev/
|
||||
51,Native,Handle permissions,Request permissions properly,Check and request permissions,Assume permissions granted,PermissionsAndroid.request(),Access without permission check,High,https://reactnative.dev/docs/permissionsandroid
|
||||
|
@@ -1,54 +0,0 @@
|
||||
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
|
||||
1,Reactivity,Use $: for reactive statements,Automatic dependency tracking,$: for derived values,Manual recalculation,$: doubled = count * 2,let doubled; count && (doubled = count * 2),Medium,https://svelte.dev/docs/svelte-components#script-3-$-marks-a-statement-as-reactive
|
||||
2,Reactivity,Trigger reactivity with assignment,Svelte tracks assignments not mutations,Reassign arrays/objects to trigger update,Mutate without reassignment,"items = [...items, newItem]",items.push(newItem),High,https://svelte.dev/docs/svelte-components#script-2-assignments-are-reactive
|
||||
3,Reactivity,Use $state in Svelte 5,Runes for explicit reactivity,let count = $state(0),Implicit reactivity in Svelte 5,let count = $state(0),let count = 0 (Svelte 5),Medium,https://svelte.dev/blog/runes
|
||||
4,Reactivity,Use $derived for computed values,$derived replaces $: in Svelte 5,let doubled = $derived(count * 2),$: in Svelte 5,let doubled = $derived(count * 2),$: doubled = count * 2 (Svelte 5),Medium,
|
||||
5,Reactivity,Use $effect for side effects,$effect replaces $: side effects,Use $effect for subscriptions,$: for side effects in Svelte 5,$effect(() => console.log(count)),$: console.log(count) (Svelte 5),Medium,
|
||||
6,Props,Export let for props,Declare props with export let,export let propName,Props without export,export let count = 0,let count = 0,High,https://svelte.dev/docs/svelte-components#script-1-export-creates-a-component-prop
|
||||
7,Props,Use $props in Svelte 5,$props rune for prop access,let { name } = $props(),export let in Svelte 5,"let { name, age = 0 } = $props()",export let name; export let age = 0,Medium,
|
||||
8,Props,Provide default values,Default props with assignment,export let count = 0,Required props without defaults,export let count = 0,export let count,Low,
|
||||
9,Props,Use spread props,Pass through unknown props,{...$$restProps} on elements,Manual prop forwarding,<button {...$$restProps}>,<button class={$$props.class}>,Low,https://svelte.dev/docs/basic-markup#attributes-and-props
|
||||
10,Bindings,Use bind: for two-way binding,Simplified input handling,bind:value for inputs,on:input with manual update,<input bind:value={name}>,<input value={name} on:input={e => name = e.target.value}>,Low,https://svelte.dev/docs/element-directives#bind-property
|
||||
11,Bindings,Bind to DOM elements,Reference DOM nodes,bind:this for element reference,querySelector in onMount,<div bind:this={el}>,onMount(() => el = document.querySelector()),Medium,
|
||||
12,Bindings,Use bind:group for radios/checkboxes,Simplified group handling,bind:group for radio/checkbox groups,Manual checked handling,"<input type=""radio"" bind:group={selected}>","<input type=""radio"" checked={selected === value}>",Low,
|
||||
13,Events,Use on: for event handlers,Event directive syntax,on:click={handler},addEventListener in onMount,<button on:click={handleClick}>,onMount(() => btn.addEventListener()),Medium,https://svelte.dev/docs/element-directives#on-eventname
|
||||
14,Events,Forward events with on:event,Pass events to parent,on:click without handler,createEventDispatcher for DOM events,<button on:click>,"dispatch('click', event)",Low,
|
||||
15,Events,Use createEventDispatcher,Custom component events,dispatch for custom events,on:event for custom events,"dispatch('save', { data })",on:save without dispatch,Medium,https://svelte.dev/docs/svelte#createeventdispatcher
|
||||
16,Lifecycle,Use onMount for initialization,Run code after component mounts,onMount for setup and data fetching,Code in script body for side effects,onMount(() => fetchData()),fetchData() in script body,High,https://svelte.dev/docs/svelte#onmount
|
||||
17,Lifecycle,Return cleanup from onMount,Automatic cleanup on destroy,Return function from onMount,Separate onDestroy for paired cleanup,onMount(() => { sub(); return unsub }),onMount(sub); onDestroy(unsub),Medium,
|
||||
18,Lifecycle,Use onDestroy sparingly,Only when onMount cleanup not possible,onDestroy for non-mount cleanup,onDestroy for mount-related cleanup,onDestroy for store unsubscribe,onDestroy(() => clearInterval(id)),Low,
|
||||
19,Lifecycle,Avoid beforeUpdate/afterUpdate,Usually not needed,Reactive statements instead,beforeUpdate for derived state,$: if (x) doSomething(),beforeUpdate(() => doSomething()),Low,
|
||||
20,Stores,Use writable for mutable state,Basic reactive store,writable for shared mutable state,Local variables for shared state,const count = writable(0),let count = 0 in module,Medium,https://svelte.dev/docs/svelte-store#writable
|
||||
21,Stores,Use readable for read-only state,External data sources,readable for derived/external data,writable for read-only data,"readable(0, set => interval(set))",writable(0) for timer,Low,https://svelte.dev/docs/svelte-store#readable
|
||||
22,Stores,Use derived for computed stores,Combine or transform stores,derived for computed values,Manual subscription for derived,"derived(count, $c => $c * 2)",count.subscribe(c => doubled = c * 2),Medium,https://svelte.dev/docs/svelte-store#derived
|
||||
23,Stores,Use $ prefix for auto-subscription,Automatic subscribe/unsubscribe,$storeName in components,Manual subscription,{$count},count.subscribe(c => value = c),High,
|
||||
24,Stores,Clean up custom subscriptions,Unsubscribe when component destroys,Return unsubscribe from onMount,Leave subscriptions open,onMount(() => store.subscribe(fn)),store.subscribe(fn) in script,High,
|
||||
25,Slots,Use slots for composition,Content projection,<slot> for flexible content,Props for all content,<slot>Default</slot>,"<Component content=""text""/>",Medium,https://svelte.dev/docs/special-elements#slot
|
||||
26,Slots,Name slots for multiple areas,Multiple content areas,"<slot name=""header"">",Single slot for complex layouts,"<slot name=""header""><slot name=""footer"">",<slot> with complex conditionals,Low,
|
||||
27,Slots,Check slot content with $$slots,Conditional slot rendering,$$slots.name for conditional rendering,Always render slot wrapper,"{#if $$slots.footer}<slot name=""footer""/>{/if}","<div><slot name=""footer""/></div>",Low,
|
||||
28,Styling,Use scoped styles by default,Styles scoped to component,<style> for component styles,Global styles for component,:global() only when needed,<style> all global,Medium,https://svelte.dev/docs/svelte-components#style
|
||||
29,Styling,Use :global() sparingly,Escape scoping when needed,:global for third-party styling,Global for all styles,:global(.external-lib),<style> without scoping,Medium,
|
||||
30,Styling,Use CSS variables for theming,Dynamic styling,CSS custom properties,Inline styles for themes,"style=""--color: {color}""","style=""color: {color}""",Low,
|
||||
31,Transitions,Use built-in transitions,Svelte transition directives,transition:fade for simple effects,Manual CSS transitions,<div transition:fade>,<div class:fade={visible}>,Low,https://svelte.dev/docs/element-directives#transition-fn
|
||||
32,Transitions,Use in: and out: separately,Different enter/exit animations,in:fly out:fade for asymmetric,Same transition for both,<div in:fly out:fade>,<div transition:fly>,Low,
|
||||
33,Transitions,Add local modifier,Prevent ancestor trigger,transition:fade|local,Global transitions for lists,<div transition:slide|local>,<div transition:slide>,Medium,
|
||||
34,Actions,Use actions for DOM behavior,Reusable DOM logic,use:action for DOM enhancements,onMount for each usage,<div use:clickOutside>,onMount(() => setupClickOutside(el)),Medium,https://svelte.dev/docs/element-directives#use-action
|
||||
35,Actions,Return update and destroy,Lifecycle methods for actions,"Return { update, destroy }",Only initial setup,"return { update(params) {}, destroy() {} }",return destroy only,Medium,
|
||||
36,Actions,Pass parameters to actions,Configure action behavior,use:action={params},Hardcoded action behavior,<div use:tooltip={options}>,<div use:tooltip>,Low,
|
||||
37,Logic,Use {#if} for conditionals,Template conditionals,{#if} {:else if} {:else},Ternary in expressions,{#if cond}...{:else}...{/if},{cond ? a : b} for complex,Low,https://svelte.dev/docs/logic-blocks#if
|
||||
38,Logic,Use {#each} for lists,List rendering,{#each} with key,Map in expression,{#each items as item (item.id)},{items.map(i => `<div>${i}</div>`)},Medium,
|
||||
39,Logic,Always use keys in {#each},Proper list reconciliation,(item.id) for unique key,Index as key or no key,{#each items as item (item.id)},"{#each items as item, i (i)}",High,
|
||||
40,Logic,Use {#await} for promises,Handle async states,{#await} for loading/error states,Manual promise handling,{#await promise}...{:then}...{:catch},{#if loading}...{#if error},Medium,https://svelte.dev/docs/logic-blocks#await
|
||||
41,SvelteKit,Use +page.svelte for routes,File-based routing,+page.svelte for route components,Custom routing setup,routes/about/+page.svelte,routes/About.svelte,Medium,https://kit.svelte.dev/docs/routing
|
||||
42,SvelteKit,Use +page.js for data loading,Load data before render,load function in +page.js,onMount for data fetching,export function load() {},onMount(() => fetchData()),High,https://kit.svelte.dev/docs/load
|
||||
43,SvelteKit,Use +page.server.js for server-only,Server-side data loading,+page.server.js for sensitive data,+page.js for API keys,+page.server.js with DB access,+page.js with DB access,High,
|
||||
44,SvelteKit,Use form actions,Server-side form handling,+page.server.js actions,API routes for forms,export const actions = { default },fetch('/api/submit'),Medium,https://kit.svelte.dev/docs/form-actions
|
||||
45,SvelteKit,Use $app/stores for app state,$page $navigating $updated,$page for current page data,Manual URL parsing,import { page } from '$app/stores',window.location.pathname,Medium,https://kit.svelte.dev/docs/modules#$app-stores
|
||||
46,Performance,Use {#key} for forced re-render,Reset component state,{#key id} for fresh instance,Manual destroy/create,{#key item.id}<Component/>{/key},on:change={() => component = null},Low,https://svelte.dev/docs/logic-blocks#key
|
||||
47,Performance,Avoid unnecessary reactivity,Not everything needs $:,$: only for side effects,$: for simple assignments,$: if (x) console.log(x),$: y = x (when y = x works),Low,
|
||||
48,Performance,Use immutable compiler option,Skip equality checks,immutable: true for large lists,Default for all components,<svelte:options immutable/>,Default without immutable,Low,
|
||||
49,TypeScript,"Use lang=""ts"" in script",TypeScript support,"<script lang=""ts"">",JavaScript for typed projects,"<script lang=""ts"">",<script> with JSDoc,Medium,https://svelte.dev/docs/typescript
|
||||
50,TypeScript,Type props with interface,Explicit prop types,interface $$Props for types,Untyped props,interface $$Props { name: string },export let name,Medium,
|
||||
51,TypeScript,Type events with createEventDispatcher,Type-safe events,createEventDispatcher<Events>(),Untyped dispatch,createEventDispatcher<{ save: Data }>(),createEventDispatcher(),Medium,
|
||||
52,Accessibility,Use semantic elements,Proper HTML in templates,button nav main appropriately,div for everything,<button on:click>,<div on:click>,High,
|
||||
53,Accessibility,Add aria to dynamic content,Accessible state changes,aria-live for updates,Silent dynamic updates,"<div aria-live=""polite"">{message}</div>",<div>{message}</div>,Medium,
|
||||
|
@@ -1,51 +0,0 @@
|
||||
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
|
||||
1,Views,Use struct for views,SwiftUI views are value types,struct MyView: View,class MyView: View,struct ContentView: View { var body: some View },class ContentView: View,High,https://developer.apple.com/documentation/swiftui/view
|
||||
2,Views,Keep views small and focused,Single responsibility for each view,Extract subviews for complex layouts,Large monolithic views,Extract HeaderView FooterView,500+ line View struct,Medium,
|
||||
3,Views,Use body computed property,body returns the view hierarchy,var body: some View { },func body() -> some View,"var body: some View { Text(""Hello"") }",func body() -> Text,High,
|
||||
4,Views,Prefer composition over inheritance,Compose views using ViewBuilder,Combine smaller views,Inheritance hierarchies,VStack { Header() Content() },class SpecialView extends BaseView,Medium,
|
||||
5,State,Use @State for local state,Simple value types owned by view,@State for view-local primitives,@State for shared data,@State private var count = 0,@State var sharedData: Model,High,https://developer.apple.com/documentation/swiftui/state
|
||||
6,State,Use @Binding for two-way data,Pass mutable state to child views,@Binding for child input,@State in child for parent data,@Binding var isOn: Bool,$isOn to pass binding,Medium,https://developer.apple.com/documentation/swiftui/binding
|
||||
7,State,Use @StateObject for reference types,ObservableObject owned by view,@StateObject for view-created objects,@ObservedObject for owned objects,@StateObject private var vm = ViewModel(),@ObservedObject var vm = ViewModel(),High,https://developer.apple.com/documentation/swiftui/stateobject
|
||||
8,State,Use @ObservedObject for injected objects,Reference types passed from parent,@ObservedObject for injected dependencies,@StateObject for injected objects,@ObservedObject var vm: ViewModel,@StateObject var vm: ViewModel (injected),High,https://developer.apple.com/documentation/swiftui/observedobject
|
||||
9,State,Use @EnvironmentObject for shared state,App-wide state injection,@EnvironmentObject for global state,Prop drilling through views,@EnvironmentObject var settings: Settings,Pass settings through 5 views,Medium,https://developer.apple.com/documentation/swiftui/environmentobject
|
||||
10,State,Use @Published in ObservableObject,Automatically publish property changes,@Published for observed properties,Manual objectWillChange calls,@Published var items: [Item] = [],var items: [Item] { didSet { objectWillChange.send() } },Medium,
|
||||
11,Observable,Use @Observable macro (iOS 17+),Modern observation without Combine,@Observable class for view models,ObservableObject for new projects,@Observable class ViewModel { },class ViewModel: ObservableObject,Medium,https://developer.apple.com/documentation/observation
|
||||
12,Observable,Use @Bindable for @Observable,Create bindings from @Observable,@Bindable var vm for bindings,@Binding with @Observable,@Bindable var viewModel,$viewModel.name with @Observable,Medium,
|
||||
13,Layout,Use VStack HStack ZStack,Standard stack-based layouts,Stacks for linear arrangements,GeometryReader for simple layouts,VStack { Text() Image() },GeometryReader for vertical list,Medium,https://developer.apple.com/documentation/swiftui/vstack
|
||||
14,Layout,Use LazyVStack LazyHStack for lists,Lazy loading for performance,Lazy stacks for long lists,Regular stacks for 100+ items,LazyVStack { ForEach(items) },VStack { ForEach(largeArray) },High,https://developer.apple.com/documentation/swiftui/lazyvstack
|
||||
15,Layout,Use GeometryReader sparingly,Only when needed for sizing,GeometryReader for responsive layouts,GeometryReader everywhere,GeometryReader for aspect ratio,GeometryReader wrapping everything,Medium,
|
||||
16,Layout,Use spacing and padding consistently,Consistent spacing throughout app,Design system spacing values,Magic numbers for spacing,.padding(16) or .padding(),".padding(13), .padding(17)",Low,
|
||||
17,Layout,Use frame modifiers correctly,Set explicit sizes when needed,.frame(maxWidth: .infinity),Fixed sizes for responsive content,.frame(maxWidth: .infinity),.frame(width: 375),Medium,
|
||||
18,Modifiers,Order modifiers correctly,Modifier order affects rendering,Background before padding for full coverage,Wrong modifier order,.padding().background(Color.red),.background(Color.red).padding(),High,
|
||||
19,Modifiers,Create custom ViewModifiers,Reusable modifier combinations,ViewModifier for repeated styling,Duplicate modifier chains,struct CardStyle: ViewModifier,.shadow().cornerRadius() everywhere,Medium,https://developer.apple.com/documentation/swiftui/viewmodifier
|
||||
20,Modifiers,Use conditional modifiers carefully,Avoid changing view identity,if-else with same view type,Conditional that changes view identity,Text(title).foregroundColor(isActive ? .blue : .gray),if isActive { Text().bold() } else { Text() },Medium,
|
||||
21,Navigation,Use NavigationStack (iOS 16+),Modern navigation with type-safe paths,NavigationStack with navigationDestination,NavigationView for new projects,NavigationStack { },NavigationView { } (deprecated),Medium,https://developer.apple.com/documentation/swiftui/navigationstack
|
||||
22,Navigation,Use navigationDestination,Type-safe navigation destinations,.navigationDestination(for:),NavigationLink(destination:),.navigationDestination(for: Item.self),NavigationLink(destination: DetailView()),Medium,
|
||||
23,Navigation,Use @Environment for dismiss,Programmatic navigation dismissal,@Environment(\.dismiss) var dismiss,presentationMode (deprecated),@Environment(\.dismiss) var dismiss,@Environment(\.presentationMode),Low,
|
||||
24,Lists,Use List for scrollable content,Built-in scrolling and styling,List for standard scrollable content,ScrollView + VStack for simple lists,List { ForEach(items) { } },ScrollView { VStack { ForEach } },Low,https://developer.apple.com/documentation/swiftui/list
|
||||
25,Lists,Provide stable identifiers,Use Identifiable or explicit id,Identifiable protocol or id parameter,Index as identifier,ForEach(items) where Item: Identifiable,"ForEach(items.indices, id: \.self)",High,
|
||||
26,Lists,Use onDelete and onMove,Standard list editing,onDelete for swipe to delete,Custom delete implementation,.onDelete(perform: delete),.onTapGesture for delete,Low,
|
||||
27,Forms,Use Form for settings,Grouped input controls,Form for settings screens,Manual grouping for forms,Form { Section { Toggle() } },VStack { Toggle() },Low,https://developer.apple.com/documentation/swiftui/form
|
||||
28,Forms,Use @FocusState for keyboard,Manage keyboard focus,@FocusState for text field focus,Manual first responder handling,@FocusState private var isFocused: Bool,UIKit first responder,Medium,https://developer.apple.com/documentation/swiftui/focusstate
|
||||
29,Forms,Validate input properly,Show validation feedback,Real-time validation feedback,Submit without validation,TextField with validation state,TextField without error handling,Medium,
|
||||
30,Async,Use .task for async work,Automatic cancellation on view disappear,.task for view lifecycle async,onAppear with Task,.task { await loadData() },onAppear { Task { await loadData() } },Medium,https://developer.apple.com/documentation/swiftui/view/task(priority:_:)
|
||||
31,Async,Handle loading states,Show progress during async operations,ProgressView during loading,Empty view during load,if isLoading { ProgressView() },No loading indicator,Medium,
|
||||
32,Async,Use @MainActor for UI updates,Ensure UI updates on main thread,@MainActor on view models,Manual DispatchQueue.main,@MainActor class ViewModel,DispatchQueue.main.async,Medium,
|
||||
33,Animation,Use withAnimation,Animate state changes,withAnimation for state transitions,No animation for state changes,withAnimation { isExpanded.toggle() },isExpanded.toggle(),Low,https://developer.apple.com/documentation/swiftui/withanimation(_:_:)
|
||||
34,Animation,Use .animation modifier,Apply animations to views,.animation(.spring()) on view,Manual animation timing,.animation(.easeInOut),CABasicAnimation equivalent,Low,
|
||||
35,Animation,Respect reduced motion,Check accessibility settings,Check accessibilityReduceMotion,Ignore motion preferences,@Environment(\.accessibilityReduceMotion),Always animate regardless,High,
|
||||
36,Preview,Use #Preview macro (Xcode 15+),Modern preview syntax,#Preview for view previews,PreviewProvider protocol,#Preview { ContentView() },struct ContentView_Previews: PreviewProvider,Low,
|
||||
37,Preview,Create multiple previews,Test different states and devices,Multiple previews for states,Single preview only,"#Preview(""Light"") { } #Preview(""Dark"") { }",Single preview configuration,Low,
|
||||
38,Preview,Use preview data,Dedicated preview mock data,Static preview data,Production data in previews,Item.preview for preview,Fetch real data in preview,Low,
|
||||
39,Performance,Avoid expensive body computations,Body should be fast to compute,Precompute in view model,Heavy computation in body,vm.computedValue in body,Complex calculation in body,High,
|
||||
40,Performance,Use Equatable views,Skip unnecessary view updates,Equatable for complex views,Default equality for all views,struct MyView: View Equatable,No Equatable conformance,Medium,
|
||||
41,Performance,Profile with Instruments,Measure before optimizing,Use SwiftUI Instruments,Guess at performance issues,Profile with Instruments,Optimize without measuring,Medium,
|
||||
42,Accessibility,Add accessibility labels,Describe UI elements,.accessibilityLabel for context,Missing labels,".accessibilityLabel(""Close button"")",Button without label,High,https://developer.apple.com/documentation/swiftui/view/accessibilitylabel(_:)-1d7jv
|
||||
43,Accessibility,Support Dynamic Type,Respect text size preferences,Scalable fonts and layouts,Fixed font sizes,.font(.body) with Dynamic Type,.font(.system(size: 16)),High,
|
||||
44,Accessibility,Use semantic views,Proper accessibility traits,Correct accessibilityTraits,Wrong semantic meaning,Button for actions Image for display,Image that acts like button,Medium,
|
||||
45,Testing,Use ViewInspector for testing,Third-party view testing,ViewInspector for unit tests,UI tests only,ViewInspector assertions,Only XCUITest,Medium,
|
||||
46,Testing,Test view models,Unit test business logic,XCTest for view model,Skip view model testing,Test ViewModel methods,No unit tests,Medium,
|
||||
47,Testing,Use preview as visual test,Previews catch visual regressions,Multiple preview configurations,No visual verification,Preview different states,Single preview only,Low,
|
||||
48,Architecture,Use MVVM pattern,Separate view and logic,ViewModel for business logic,Logic in View,ObservableObject ViewModel,@State for complex logic,Medium,
|
||||
49,Architecture,Keep views dumb,Views display view model state,View reads from ViewModel,Business logic in View,view.items from vm.items,Complex filtering in View,Medium,
|
||||
50,Architecture,Use dependency injection,Inject dependencies for testing,Initialize with dependencies,Hard-coded dependencies,init(service: ServiceProtocol),let service = RealService(),Medium,
|
||||
|
@@ -1,50 +0,0 @@
|
||||
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
|
||||
1,Composition,Use Composition API for new projects,Composition API offers better TypeScript support and logic reuse,<script setup> for components,Options API for new projects,<script setup>,export default { data() },Medium,https://vuejs.org/guide/extras/composition-api-faq.html
|
||||
2,Composition,Use script setup syntax,Cleaner syntax with automatic exports,<script setup> with defineProps,setup() function manually,<script setup>,<script> setup() { return {} },Low,https://vuejs.org/api/sfc-script-setup.html
|
||||
3,Reactivity,Use ref for primitives,ref() for primitive values that need reactivity,ref() for strings numbers booleans,reactive() for primitives,const count = ref(0),const count = reactive(0),Medium,https://vuejs.org/guide/essentials/reactivity-fundamentals.html
|
||||
4,Reactivity,Use reactive for objects,reactive() for complex objects and arrays,reactive() for objects with multiple properties,ref() for complex objects,const state = reactive({ user: null }),const state = ref({ user: null }),Medium,
|
||||
5,Reactivity,Access ref values with .value,Remember .value in script unwrap in template,Use .value in script,Forget .value in script,count.value++,count++ (in script),High,
|
||||
6,Reactivity,Use computed for derived state,Computed properties cache and update automatically,computed() for derived values,Methods for derived values,const doubled = computed(() => count.value * 2),const doubled = () => count.value * 2,Medium,https://vuejs.org/guide/essentials/computed.html
|
||||
7,Reactivity,Use shallowRef for large objects,Avoid deep reactivity for performance,shallowRef for large data structures,ref for large nested objects,const bigData = shallowRef(largeObject),const bigData = ref(largeObject),Medium,https://vuejs.org/api/reactivity-advanced.html#shallowref
|
||||
8,Watchers,Use watchEffect for simple cases,Auto-tracks dependencies,watchEffect for simple reactive effects,watch with explicit deps when not needed,watchEffect(() => console.log(count.value)),"watch(count, (val) => console.log(val))",Low,https://vuejs.org/guide/essentials/watchers.html
|
||||
9,Watchers,Use watch for specific sources,Explicit control over what to watch,watch with specific refs,watchEffect for complex conditional logic,"watch(userId, fetchUser)",watchEffect with conditionals,Medium,
|
||||
10,Watchers,Clean up side effects,Return cleanup function in watchers,Return cleanup in watchEffect,Leave subscriptions open,watchEffect((onCleanup) => { onCleanup(unsub) }),watchEffect without cleanup,High,
|
||||
11,Props,Define props with defineProps,Type-safe prop definitions,defineProps with TypeScript,Props without types,defineProps<{ msg: string }>(),defineProps(['msg']),Medium,https://vuejs.org/guide/typescript/composition-api.html#typing-component-props
|
||||
12,Props,Use withDefaults for default values,Provide defaults for optional props,withDefaults with defineProps,Defaults in destructuring,"withDefaults(defineProps<Props>(), { count: 0 })",const { count = 0 } = defineProps(),Medium,
|
||||
13,Props,Avoid mutating props,Props should be read-only,Emit events to parent for changes,Direct prop mutation,"emit('update:modelValue', newVal)",props.modelValue = newVal,High,
|
||||
14,Emits,Define emits with defineEmits,Type-safe event emissions,defineEmits with types,Emit without definition,defineEmits<{ change: [id: number] }>(),"emit('change', id) without define",Medium,https://vuejs.org/guide/typescript/composition-api.html#typing-component-emits
|
||||
15,Emits,Use v-model for two-way binding,Simplified parent-child data flow,v-model with modelValue prop,:value + @input manually,"<Child v-model=""value""/>","<Child :value=""value"" @input=""value = $event""/>",Low,https://vuejs.org/guide/components/v-model.html
|
||||
16,Lifecycle,Use onMounted for DOM access,DOM is ready in onMounted,onMounted for DOM operations,Access DOM in setup directly,onMounted(() => el.value.focus()),el.value.focus() in setup,High,https://vuejs.org/api/composition-api-lifecycle.html
|
||||
17,Lifecycle,Clean up in onUnmounted,Remove listeners and subscriptions,onUnmounted for cleanup,Leave listeners attached,onUnmounted(() => window.removeEventListener()),No cleanup on unmount,High,
|
||||
18,Lifecycle,Avoid onBeforeMount for data,Use onMounted or setup for data fetching,Fetch in onMounted or setup,Fetch in onBeforeMount,onMounted(async () => await fetchData()),onBeforeMount(async () => await fetchData()),Low,
|
||||
19,Components,Use single-file components,Keep template script style together,.vue files for components,Separate template/script files,Component.vue with all parts,Component.js + Component.html,Low,
|
||||
20,Components,Use PascalCase for components,Consistent component naming,PascalCase in imports and templates,kebab-case in script,<MyComponent/>,<my-component/>,Low,https://vuejs.org/style-guide/rules-strongly-recommended.html
|
||||
21,Components,Prefer composition over mixins,Composables replace mixins,Composables for shared logic,Mixins for code reuse,const { data } = useApi(),mixins: [apiMixin],Medium,
|
||||
22,Composables,Name composables with use prefix,Convention for composable functions,useFetch useAuth useForm,getData or fetchApi,export function useFetch(),export function fetchData(),Medium,https://vuejs.org/guide/reusability/composables.html
|
||||
23,Composables,Return refs from composables,Maintain reactivity when destructuring,Return ref values,Return reactive objects that lose reactivity,return { data: ref(null) },return reactive({ data: null }),Medium,
|
||||
24,Composables,Accept ref or value params,Use toValue for flexible inputs,toValue() or unref() for params,Only accept ref or only value,const val = toValue(maybeRef),const val = maybeRef.value,Low,https://vuejs.org/api/reactivity-utilities.html#tovalue
|
||||
25,Templates,Use v-bind shorthand,Cleaner template syntax,:prop instead of v-bind:prop,Full v-bind syntax,"<div :class=""cls"">","<div v-bind:class=""cls"">",Low,
|
||||
26,Templates,Use v-on shorthand,Cleaner event binding,@event instead of v-on:event,Full v-on syntax,"<button @click=""handler"">","<button v-on:click=""handler"">",Low,
|
||||
27,Templates,Avoid v-if with v-for,v-if has higher priority causes issues,Wrap in template or computed filter,v-if on same element as v-for,<template v-for><div v-if>,<div v-for v-if>,High,https://vuejs.org/style-guide/rules-essential.html#avoid-v-if-with-v-for
|
||||
28,Templates,Use key with v-for,Proper list rendering and updates,Unique key for each item,Index as key for dynamic lists,"v-for=""item in items"" :key=""item.id""","v-for=""(item, i) in items"" :key=""i""",High,
|
||||
29,State,Use Pinia for global state,Official state management for Vue 3,Pinia stores for shared state,Vuex for new projects,const store = useCounterStore(),Vuex with mutations,Medium,https://pinia.vuejs.org/
|
||||
30,State,Define stores with defineStore,Composition API style stores,Setup stores with defineStore,Options stores for complex state,"defineStore('counter', () => {})","defineStore('counter', { state })",Low,
|
||||
31,State,Use storeToRefs for destructuring,Maintain reactivity when destructuring,storeToRefs(store),Direct destructuring,const { count } = storeToRefs(store),const { count } = store,High,https://pinia.vuejs.org/core-concepts/#destructuring-from-a-store
|
||||
32,Routing,Use useRouter and useRoute,Composition API router access,useRouter() useRoute() in setup,this.$router this.$route,const router = useRouter(),this.$router.push(),Medium,https://router.vuejs.org/guide/advanced/composition-api.html
|
||||
33,Routing,Lazy load route components,Code splitting for routes,() => import() for components,Static imports for all routes,component: () => import('./Page.vue'),component: Page,Medium,https://router.vuejs.org/guide/advanced/lazy-loading.html
|
||||
34,Routing,Use navigation guards,Protect routes and handle redirects,beforeEach for auth checks,Check auth in each component,router.beforeEach((to) => {}),Check auth in onMounted,Medium,
|
||||
35,Performance,Use v-once for static content,Skip re-renders for static elements,v-once on never-changing content,v-once on dynamic content,<div v-once>{{ staticText }}</div>,<div v-once>{{ dynamicText }}</div>,Low,https://vuejs.org/api/built-in-directives.html#v-once
|
||||
36,Performance,Use v-memo for expensive lists,Memoize list items,v-memo with dependency array,Re-render entire list always,"<div v-for v-memo=""[item.id]"">",<div v-for> without memo,Medium,https://vuejs.org/api/built-in-directives.html#v-memo
|
||||
37,Performance,Use shallowReactive for flat objects,Avoid deep reactivity overhead,shallowReactive for flat state,reactive for simple objects,shallowReactive({ count: 0 }),reactive({ count: 0 }),Low,
|
||||
38,Performance,Use defineAsyncComponent,Lazy load heavy components,defineAsyncComponent for modals dialogs,Import all components eagerly,defineAsyncComponent(() => import()),import HeavyComponent from,Medium,https://vuejs.org/guide/components/async.html
|
||||
39,TypeScript,Use generic components,Type-safe reusable components,Generic with defineComponent,Any types in components,"<script setup lang=""ts"" generic=""T"">",<script setup> without types,Medium,https://vuejs.org/guide/typescript/composition-api.html
|
||||
40,TypeScript,Type template refs,Proper typing for DOM refs,ref<HTMLInputElement>(null),ref(null) without type,const input = ref<HTMLInputElement>(null),const input = ref(null),Medium,
|
||||
41,TypeScript,Use PropType for complex props,Type complex prop types,PropType<User> for object props,Object without type,type: Object as PropType<User>,type: Object,Medium,
|
||||
42,Testing,Use Vue Test Utils,Official testing library,mount shallowMount for components,Manual DOM testing,import { mount } from '@vue/test-utils',document.createElement,Medium,https://test-utils.vuejs.org/
|
||||
43,Testing,Test component behavior,Focus on inputs and outputs,Test props emit and rendered output,Test internal implementation,expect(wrapper.text()).toContain(),expect(wrapper.vm.internalState),Medium,
|
||||
44,Forms,Use v-model modifiers,Built-in input handling,.lazy .number .trim modifiers,Manual input parsing,"<input v-model.number=""age"">","<input v-model=""age""> then parse",Low,https://vuejs.org/guide/essentials/forms.html#modifiers
|
||||
45,Forms,Use VeeValidate or FormKit,Form validation libraries,VeeValidate for complex forms,Manual validation logic,useField useForm from vee-validate,Custom validation in each input,Medium,
|
||||
46,Accessibility,Use semantic elements,Proper HTML elements in templates,button nav main for purpose,div for everything,<button @click>,<div @click>,High,
|
||||
47,Accessibility,Bind aria attributes dynamically,Keep ARIA in sync with state,":aria-expanded=""isOpen""",Static ARIA values,":aria-expanded=""menuOpen""","aria-expanded=""true""",Medium,
|
||||
48,SSR,Use Nuxt for SSR,Full-featured SSR framework,Nuxt 3 for SSR apps,Manual SSR setup,npx nuxi init my-app,Custom SSR configuration,Medium,https://nuxt.com/
|
||||
49,SSR,Handle hydration mismatches,Client/server content must match,ClientOnly for browser-only content,Different content server/client,<ClientOnly><BrowserWidget/></ClientOnly>,<div>{{ Date.now() }}</div>,High,
|
||||
|
@@ -76,13 +76,6 @@ STACK_CONFIG = {
|
||||
"html-tailwind": {"file": "stacks/html-tailwind.csv"},
|
||||
"react": {"file": "stacks/react.csv"},
|
||||
"nextjs": {"file": "stacks/nextjs.csv"},
|
||||
"vue": {"file": "stacks/vue.csv"},
|
||||
"nuxtjs": {"file": "stacks/nuxtjs.csv"},
|
||||
"nuxt-ui": {"file": "stacks/nuxt-ui.csv"},
|
||||
"svelte": {"file": "stacks/svelte.csv"},
|
||||
"swiftui": {"file": "stacks/swiftui.csv"},
|
||||
"react-native": {"file": "stacks/react-native.csv"},
|
||||
"flutter": {"file": "stacks/flutter.csv"},
|
||||
"shadcn": {"file": "stacks/shadcn.csv"}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ Usage: python search.py "<query>" [--domain <domain>] [--stack <stack>] [--max-r
|
||||
python search.py "<query>" --design-system [-p "Project Name"]
|
||||
|
||||
Domains: style, prompt, color, chart, landing, product, ux, typography
|
||||
Stacks: html-tailwind, react, nextjs
|
||||
Stacks: html-tailwind, react, nextjs, shadcn
|
||||
"""
|
||||
|
||||
import argparse
|
||||
@@ -44,7 +44,7 @@ if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="UI Pro Max Search")
|
||||
parser.add_argument("query", help="Search query")
|
||||
parser.add_argument("--domain", "-d", choices=list(CSV_CONFIG.keys()), help="Search domain")
|
||||
parser.add_argument("--stack", "-s", choices=AVAILABLE_STACKS, help="Stack-specific search (html-tailwind, react, nextjs)")
|
||||
parser.add_argument("--stack", "-s", choices=AVAILABLE_STACKS, help="Stack-specific search (html-tailwind, react, nextjs, shadcn)")
|
||||
parser.add_argument("--max-results", "-n", type=int, default=MAX_RESULTS, help="Max results (default: 3)")
|
||||
parser.add_argument("--json", action="store_true", help="Output as JSON")
|
||||
# Design system generation
|
||||
|
||||
15
.dockerignore
Normal file
@@ -0,0 +1,15 @@
|
||||
node_modules
|
||||
.next
|
||||
.git
|
||||
.agents
|
||||
.claude
|
||||
.mcp.json
|
||||
*.md
|
||||
.env*
|
||||
!.env.example
|
||||
drizzle/
|
||||
data/
|
||||
!data/app.db
|
||||
!data/yokatlas.db
|
||||
!data/yokatlas.db-wal
|
||||
!data/yokatlas.db-shm
|
||||
35
.gitea/workflows/ci.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
name: Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
steps:
|
||||
- name: Kaynak kodu çek
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: .env.production oluştur
|
||||
run: |
|
||||
cat > .env.production <<'EOF'
|
||||
BETTER_AUTH_SECRET=${{ secrets.BETTER_AUTH_SECRET }}
|
||||
BETTER_AUTH_URL=${{ secrets.BETTER_AUTH_URL }}
|
||||
NEXT_PUBLIC_APP_URL=${{ secrets.NEXT_PUBLIC_APP_URL }}
|
||||
GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}
|
||||
GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }}
|
||||
RESEND_API_KEY=${{ secrets.RESEND_API_KEY }}
|
||||
EMAIL_FROM=${{ secrets.EMAIL_FROM }}
|
||||
IYZICO_API_KEY=${{ secrets.IYZICO_API_KEY }}
|
||||
IYZICO_SECRET_KEY=${{ secrets.IYZICO_SECRET_KEY }}
|
||||
IYZICO_BASE_URL=${{ secrets.IYZICO_BASE_URL }}
|
||||
ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_API_KEY }}
|
||||
EOF
|
||||
|
||||
- name: Build & deploy
|
||||
run: |
|
||||
docker compose -p kolaytercih up -d --build --remove-orphans
|
||||
docker image prune -f
|
||||
24
AGENTS.md
@@ -2,4 +2,28 @@
|
||||
# This is NOT the Next.js you know
|
||||
|
||||
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
|
||||
|
||||
# Tarayıcı açma
|
||||
|
||||
UI değişikliklerini tarayıcıda/preview'da doğrulamaya çalışma; kullanıcı kendisi kontrol ediyor. Dev sunucusu veya browser paneli açma — sadece kod değişikliğini yap ve ne değiştiğini raporla.
|
||||
|
||||
# Push öncesi build zorunlu
|
||||
|
||||
Push emri geldiğinde önce lokalde `pnpm build` başarıyla geçmeli; geçmeden asla push etme. Kritik detay: çalışma ağacı kirliyken build, commit'lenmemiş dosyaları da gördüğü için CI'da kırılacak bir commit'i yakalayamayabilir. Bu yüzden build'i **push edilecek commit'in kendisi** üzerinde doğrula (ör. geçici `git worktree add <dir> HEAD` + `node_modules` symlink'i ile). Ayrıca kısmi commit atarken değişikliğin bağımlılık kapanışını kontrol et — bir dosyanın kullandığı prop/export başka bir commit'lenmemiş dosyadan geliyorsa onları da aynı commit'e dahil et.
|
||||
|
||||
# Badge/eyebrow rozetleri: tek kaynak SectionEyebrow
|
||||
|
||||
Site genelindeki tüm badge/rozet/eyebrow elemanları ana sayfadaki section başlıklarının üstünde duran rozetle birebir aynı olmalı. Kanonik bileşen `src/components/pixel-decor.tsx` içindeki `SectionEyebrow`dur (piksel imzalı `PixelMark` ikonu + `rounded-full border border-slate-200 bg-white px-3.5 py-1.5 text-xs font-semibold uppercase tracking-[0.12em] text-primary`). Yeni bir badge/eyebrow gerektiğinde `SectionEyebrow` kullan (`className` prop'u kenar boşluğu için var); `@/components/ui/badge`'deki `Badge` ile ya da elle yazılmış pill span'lerle yeni badge tasarlama. İnteraktif chip/buton pill'leri (filtre çipleri, nav butonları) bu kuralın dışındadır.
|
||||
|
||||
# UI tutarlılığı: ortak elemanlar tek kaynaktan
|
||||
|
||||
Modallar arası ortak elemanlar (kapatma çarpısı, başlık düzeni vb.) görsel olarak birebir aynı olmalı. Kapatma çarpısının kanonik stili `src/components/ui/dialog.tsx` içindeki `DialogContent` varsayılan butonudur (yuvarlak, `size-9`, `border border-slate-200`, `size-4` X ikonu, hover'da `bg-slate-100`, `active:scale-[0.96]`). Yeni bir modal eklerken bu varsayılanı kullan; özel yerleşim gerekiyorsa (ör. katalog-arama'da input satırının içindeki buton) `showCloseButton={false}` ver ama **aynı class setini** kopyala — farklı boyut/renk/varyantta yeni bir çarpı tasarlama. Aynı prensip diğer tekrarlanan UI parçaları için de geçerli: bir eleman iki yerde görünüyorsa stilini tek kaynaktan al veya birebir eşleştir.
|
||||
|
||||
# CTA butonlarında ikon: yıldız yok, sağ ok metnin sonunda
|
||||
|
||||
Funnel CTA butonlarında ("Listemi oluştur", "Tercihlerimi belirle", giriş/ödeme CTA'ları vb.) `Sparkles` (yıldız) ikonu kullanılmaz. Kanonik desen: buton metni önce gelir, sonunda `<ArrowRight className="size-4" aria-hidden />` durur. Yeni bir CTA butonu eklerken bu deseni uygula; metnin başına ikon koyma. Dekoratif `Sparkles` kullanımları (boş durum başlık ikonları, bilgi satırları) bu kuralın dışındadır — kural yalnızca aksiyon butonları/CTA linkleri içindir.
|
||||
|
||||
# Meraklısına'daki mermaid şeması mimariyle senkron kalmalı
|
||||
|
||||
`/meraklisina` sayfasındaki sihirbaz akış şeması (`src/app/meraklisina/huni-semasi.tsx` içindeki `SEMA` sabiti) ürünün gerçek davranışının belgesidir, dekor değildir. Sihirbaz/listeleme mimarisinde davranış değiştiren her değişiklikte bu şema da aynı PR/commit içinde güncellenmeli: sihirbaz adımlarının sayısı-sırası-içeriği (alan → il → devlet/vakıf), aday havuzu kuralları, 24'lük liste iskeleti (hayal/dengeli/garanti dağılımı), havuz 24'ün altına düşünce filtre gevşetme sırası ve yapay zekânın havuz-dışına-çıkamama kuralı. Şemayı güncellerken çevresindeki unsurları da eşitle: bölümdeki anlatım metni (`src/app/meraklisina/page.tsx`, 4. bölüm), kabın `aria-label`'ı ve figcaption. Şema öğrenci diliyle kalmalı (SQL/prompt/teknik detay yok) ve ürünün risk renk dilini korumalı — kırmızı/sarı/yeşil her zaman metin etiketiyle birlikte, renk tek başına anlam taşımaz.
|
||||
<!-- END:nextjs-agent-rules -->
|
||||
|
||||
106
CTA-CEKMECE-TASARIMI.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# CTA çekmecesi tasarım algısı — "Sıralamanla nereye yerleşirsin? Saniyede gör."
|
||||
|
||||
Bu doküman, programatik SEO sayfalarındaki funnel CTA'sının (`src/components/cta-sira-form.tsx`)
|
||||
alttan açılan çekmece (drawer) tasarımının arkasındaki algıyı ve kuralları belgeler.
|
||||
Yeni bir funnel giriş noktası eklerken ya da bu bileşeni değiştirirken buradaki
|
||||
ilkelere uy.
|
||||
|
||||
## 1. Temel algı: vaadi verdiğin yerde tahsil et
|
||||
|
||||
Eski davranış adayı ana sayfaya (`/`) gönderiyordu: "Saniyede gör" vaadi verip
|
||||
saniyeler süren bir sayfa geçişi ve bağlam kaybı yaşatıyordu. Yeni algı şu:
|
||||
|
||||
- **Kart vaat eder** — SEO sayfasının içinde duran kart (`bg-primary/5`,
|
||||
`border-primary/20`) merak uyandırır: "Sıralamanla nereye yerleşirsin?"
|
||||
- **Çekmece tahsil eder** — CTA butonu sayfadan koparmadan alttan bir çekmece
|
||||
açar; sıralama girişi, sihirbaz adımları ve tamamlama hepsi aynı bağlamda akar.
|
||||
- **Ödül `/sonuc`'ta** — seçimler tamamlanınca profil yazılır, çekmece kapanır
|
||||
ve aday doğrudan sonuç sayfasına gider. Sayfa geçişi yalnızca ödül anında olur.
|
||||
|
||||
Akış: **kart (vaat) → çekmece (sıralama) → sihirbaz (kişiselleştirme) → /sonuc (ödül)**.
|
||||
|
||||
Profilli adayda çekmece hiç devreye girmez: kayıtlı sıralamayla doğrudan
|
||||
`/sonuc` linki gösterilir — sıralamasını girmiş adaya bir daha girmesini
|
||||
söylemeyiz.
|
||||
|
||||
## 2. Neden çekmece, modal değil?
|
||||
|
||||
- Çekmece **sayfanın üstüne değil, altına eklenir** algısı verir: aday hâlâ
|
||||
okuduğu üniversite/bölüm sayfasının üzerindedir, içerik kaybolmaz (overlay
|
||||
hafif: `bg-black/10` + blur).
|
||||
- Alttan gelen yüzey mobilde başparmak menzilinde; hedef kitle (YKS adayı)
|
||||
ağırlıkla mobilde.
|
||||
- Swipe-to-dismiss (tutamaktan) ve overlay/Escape ile kaçış ucuz: "bir bakayım"
|
||||
maliyeti düşük tutulur. `handleOnly` kullanılır ki form/sihirbaz içindeki
|
||||
kaydırmalar çekmeceyi yanlışlıkla kapatmasın.
|
||||
- Desktop'ta çekmece tam genişliğe yayılmaz: `sm:max-w-2xl` ile ortalanır,
|
||||
`sm:border-x + sm:shadow-2xl` ile sayfadan yükselen bir panel gibi durur
|
||||
(liste çekmecesiyle aynı reçete).
|
||||
|
||||
## 3. Görsel dil: yeni hiçbir şey icat etme
|
||||
|
||||
Çekmecedeki her parça sitede zaten var olan kanonik kaynaktan gelir:
|
||||
|
||||
| Parça | Kaynak / kural |
|
||||
| --- | --- |
|
||||
| Eyebrow rozeti ("Saniyede gör") | `SectionEyebrow` (`pixel-decor.tsx`) — elle pill yazılmaz |
|
||||
| Kapatma çarpısı | `dialog.tsx`'teki kanonik set: `size-9`, `rounded-full`, `border-slate-200`, `size-4` X, hover `bg-slate-100`, `active:scale-[0.96]` |
|
||||
| CTA butonları | Metin önce, sonda `ArrowRight` (`size-4`); yıldız/Sparkles yok; `bg-orange-500 → hover:bg-orange-600` |
|
||||
| Puan türü çipleri | Hero formundaki radiogroup çipleriyle birebir aynı class seti |
|
||||
| Sıralama girişi | Profil kapısındaki desen: sola `Trophy` ikonu, `h-12`, `pl-11` |
|
||||
| Kanıt üçlüsü | Arama funnel kartıyla aynı üçlü: 24 tercihlik plan / Risk analizi / YÖK Atlas verisi (`ListChecks`, `ChartNoAxesCombined`, `Database`) |
|
||||
| Başlık/kopya tipografisi | `font-heading` bold başlık, `text-slate-600` gövde, `text-slate-900` vurgu |
|
||||
|
||||
Algı hedefi: çekmece açıldığında aday "yeni bir yere geldim" değil, "aynı ürünün
|
||||
bir katmanı kalktı" hissetmeli. Bu yüzden çekmeceye özgü hiçbir yeni renk,
|
||||
rozet, buton varyantı tasarlanmaz.
|
||||
|
||||
## 4. İçerik tonu
|
||||
|
||||
- Öğrenci diliyle, ikinci tekil: "Sıralamanı yaz", "bu sayfadan ayrılmadan gör".
|
||||
- Sürtünme kaldıran güvence her zaman görünür: **"Ücretsiz, üyelik gerekmez."**
|
||||
- Kanıt üçlüsü süs değil, ürün vaadinin özetidir; metin etiketleri ikonsuz da
|
||||
anlamlı olmalı (renk/ikon tek başına anlam taşımaz — ürünün risk renk dili
|
||||
kuralıyla aynı ilke).
|
||||
- Buton etiketleri eylemin sonucunu söyler: "Programları gör" (girdi adımı),
|
||||
"Ücretsiz tablonu gör" / "AI listemi kur (3 kredi)" (sihirbaz sonu, girişe göre).
|
||||
|
||||
## 5. Davranış ve teknik algı
|
||||
|
||||
- **Statik kalır:** Kart RSC sayfalarında prerender edilir; oturum bilgisi
|
||||
mount'ta değil, facet isteğiyle **paralel** çözülür (hero formundaki desen) —
|
||||
landing başına gereksiz auth turu atılmaz.
|
||||
- **Preload:** CTA butonuna `pointerenter`/`focus` ve sıralama inputuna `focus`
|
||||
geldiğinde `preloadSihirbazAdimlar()` çalışır; sihirbaz açıldığında chunk
|
||||
çoktan inmiştir. "Saniyede gör" vaadi teknik olarak da tutulur.
|
||||
- **İki adım, tek yüzey:** çekmece içinde `sira → sihirbaz` adımları vardır;
|
||||
erişilebilir ad sabittir (sr-only `DrawerTitle`/`DrawerDescription`), görünür
|
||||
başlıklar adıma göre değişir.
|
||||
- **Kapanış = sıfırlama, ama nazikçe:** çekmece kapanınca adım ve facet'ler
|
||||
sıfırlanır; adayın yazdığı sıralama ve puan türü **korunur** (tekrar açarsa
|
||||
baştan yazmasın).
|
||||
- **Tamamlanınca:** `tercihProfiliYaz` → çekmece kapanır → `sonucHref` ile
|
||||
`/sonuc` (girişliye `sihirbaz: "1"`, girişsize `hazir: "1"`). Giriş duvarı
|
||||
sihirbazın hemen arkasında değildir; değer önce gösterilir.
|
||||
- **Lenis:** çekmece içeriği ve kaydırma kabı `data-lenis-prevent` taşır;
|
||||
sayfadaki smooth-scroll çekmece içi kaydırmayı ezmez.
|
||||
|
||||
## 6. Erişilebilirlik
|
||||
|
||||
- Sıralama alanı: `inputMode="numeric"`, binlik ayraçlı biçimleme
|
||||
(85000 → 85.000), hata durumunda `aria-invalid` + `aria-describedby` +
|
||||
`role="alert"`.
|
||||
- Puan türü seçimi `role="radiogroup"` / `role="radio"` + `aria-checked`.
|
||||
- Kapatma yolları: çarpı butonu, overlay, Escape, tutamaktan swipe.
|
||||
- `prefers-reduced-motion` vaul/motion tarafında zaten sadeleşir; çekmeceye
|
||||
özel ek animasyon eklenmedi.
|
||||
|
||||
## 7. Bu deseni ne zaman kullan / kullanma
|
||||
|
||||
**Kullan:** İçerik sayfasında duran ve adaydan tek kritik girdi (sıralama)
|
||||
isteyen her funnel girişi. Adayın okuduğu bağlam değerliyse (bölüm, üniversite,
|
||||
rehber) çekmece doğru araçtır.
|
||||
|
||||
**Kullanma:** Zaten modal/dialog içinde olan akışlar (arama modalındaki funnel
|
||||
kartı gibi — modal üstüne çekmece açılmaz, oradaki kart mevcut kapı/dialog
|
||||
akışını kullanır) ve profilli kısayollar (doğrudan link yeterli).
|
||||
55
Dockerfile
Normal file
@@ -0,0 +1,55 @@
|
||||
FROM node:20-alpine AS base
|
||||
|
||||
# pnpm kurulumu
|
||||
RUN corepack enable && corepack prepare pnpm@10.8.1 --activate
|
||||
|
||||
# ── Bağımlılık katmanı ──
|
||||
FROM base AS deps
|
||||
WORKDIR /app
|
||||
# better-sqlite3 Alpine'de kaynaktan derleniyor (musl için prebuilt yok)
|
||||
RUN apk add --no-cache python3 make g++
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# ── Derleme katmanı ──
|
||||
FROM base AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
# data/ .dockerignore'da; libsql build sırasında file:./data/app.db açabilsin diye boş dizin gerekli
|
||||
RUN mkdir -p data && pnpm build
|
||||
|
||||
# ── Çalıştırma katmanı ──
|
||||
FROM node:20-alpine AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
|
||||
RUN addgroup --system --gid 1001 nodejs && \
|
||||
adduser --system --uid 1001 nextjs
|
||||
|
||||
# Bağımlılıklar
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/.next/standalone ./
|
||||
COPY --from=builder /app/.next/static ./.next/static
|
||||
COPY --from=builder /app/public ./public
|
||||
|
||||
# Seed veritabanları: entrypoint açılışta bunları /app/data volume'üne kopyalar
|
||||
COPY data/ ./seed/
|
||||
COPY scripts/docker-entrypoint.sh ./docker-entrypoint.sh
|
||||
|
||||
# SQLite veri dizini
|
||||
RUN chmod +x /app/docker-entrypoint.sh && \
|
||||
mkdir -p /app/data && \
|
||||
chown -R nextjs:nodejs /app/data /app/seed
|
||||
|
||||
USER nextjs
|
||||
|
||||
EXPOSE 3000
|
||||
ENV PORT=3000
|
||||
ENV HOSTNAME="0.0.0.0"
|
||||
|
||||
CMD ["/app/docker-entrypoint.sh"]
|
||||
239
GAMIFICATION.md
Normal file
@@ -0,0 +1,239 @@
|
||||
# Kolay Tercih — Gamification ve Listeye Ekleme Kurgusu
|
||||
|
||||
> Durum: Ürün kararı
|
||||
> Son güncelleme: 1 Ağustos 2026
|
||||
|
||||
## Ana fikir
|
||||
|
||||
Kolay Tercih'te bütün deneyim kullanıcının başarı sıralaması üzerine inşa
|
||||
edilir. Amaç kullanıcıya yalnızca erişebileceği programları göstermek değil;
|
||||
seçtiği programların sıralamasına, ilgi alanlarına ve önceliklerine ne kadar
|
||||
uyduğunu açıklayarak tercihine ışık tutmaktır.
|
||||
|
||||
Gamification; puan, rozet veya yapay rekabet üzerinden değil, kullanıcının
|
||||
belirsiz bir fikirden gerekçeli ve dengeli bir tercih listesine ilerlemesi
|
||||
üzerinden çalışır.
|
||||
|
||||
## Değişmez ürün kuralları
|
||||
|
||||
1. Başarı sıralaması bütün hesaplamaların başlangıç noktasıdır.
|
||||
2. Listeye yalnızca tekil bir program eklenir. Üniversitenin veya bölümün tamamı
|
||||
listeye eklenmez.
|
||||
3. Program satırlarında erişilebilir bir `+` düğmesi bulunur.
|
||||
4. Kullanıcı sihirbazı doldurmadan ilk programı listesine ekleyemez.
|
||||
5. Sihirbaz tamamlandıktan sonra `+` ile seçilen program doğrudan listeye
|
||||
eklenir; uyumsuz programlar engellenmez.
|
||||
6. Sistem kullanıcının yerine karar vermez. Çelişkileri görünür kılar, nedenini
|
||||
açıklar ve son kararı kullanıcıya bırakır.
|
||||
7. “Garanti kazanırsın” gibi kesinlik bildiren ifadeler kullanılmaz. Risk ve
|
||||
uyum değerlendirmeleri geçmiş YÖK Atlas verilerine dayalı rehberliktir.
|
||||
|
||||
## Kullanıcı yolculuğu
|
||||
|
||||
### 1. Sıralamayı öğren
|
||||
|
||||
Kullanıcı başarı sıralamasını ve puan türünü girer. Sistem buna göre program
|
||||
havuzunu, hayal/dengeli/güvenli aralıklarını ve kullanılabilir sihirbaz
|
||||
seçeneklerini oluşturur.
|
||||
|
||||
### 2. Niyetini öğren
|
||||
|
||||
Kullanıcı ilk kez bir programdaki `+` düğmesine bastığında sihirbaz seçimleri
|
||||
yoksa program hemen eklenmez. Tıklanan program “bekleyen program” olarak
|
||||
korunur ve kısa sihirbaz açılır.
|
||||
|
||||
Sihirbaz en az şu bilgileri toplar:
|
||||
|
||||
- İlgi alanları
|
||||
- Tercih edilen şehirler
|
||||
- Devlet/vakıf tercihi
|
||||
- Kariyer ve yaşam öncelikleri
|
||||
|
||||
Sihirbaz giriş mesajı:
|
||||
|
||||
> Önce seni biraz tanıyalım
|
||||
>
|
||||
> Sadece sıralamana uyan bir liste değil, ne istediğine de uyan bir tercih
|
||||
> listesi kurmak istiyoruz. Birkaç kısa seçim yap; eklediğin programların sana
|
||||
> ne kadar uyduğunu birlikte değerlendirelim.
|
||||
|
||||
Kısa alternatif:
|
||||
|
||||
> Tercihine ışık tutabilmemiz için önce ne istediğini öğrenelim.
|
||||
|
||||
Birincil eylem:
|
||||
|
||||
> Tercihlerimi belirle
|
||||
|
||||
İkincil eylem:
|
||||
|
||||
> Vazgeç
|
||||
|
||||
Sihirbaz zorunludur; “şimdilik atla ve ekle” seçeneği bulunmaz.
|
||||
|
||||
### 3. İlk programı ekle
|
||||
|
||||
Sihirbaz başarıyla tamamlandığında kullanıcının daha önce `+` ile seçtiği
|
||||
bekleyen program otomatik olarak listeye eklenir. Kullanıcı aynı programı
|
||||
yeniden bulmak veya tekrar `+` düğmesine basmak zorunda kalmaz.
|
||||
|
||||
Başarı bildirimi:
|
||||
|
||||
> Program listene eklendi. Sıralamana ve tercihlerine göre değerlendirdik.
|
||||
|
||||
### 4. Listeyi bilinçli biçimde geliştir
|
||||
|
||||
Sihirbaz tamamlandıktan sonraki `+` tıklamaları programı doğrudan ekler.
|
||||
Sistem ekleme öncesinde onay modalı göstermez ve uyumsuz seçimleri engellemez.
|
||||
Her programın değerlendirmesi listede görünür.
|
||||
|
||||
## Program değerlendirme modeli
|
||||
|
||||
Her eklenen program iki ayrı eksende değerlendirilir:
|
||||
|
||||
### Yerleşme riski
|
||||
|
||||
Kullanıcının başarı sıralaması ile programın güncel ve geçmiş taban
|
||||
sıralamaları karşılaştırılır.
|
||||
|
||||
Örnek durumlar:
|
||||
|
||||
- Hayal
|
||||
- Dengeli
|
||||
- Daha güvenli
|
||||
- Veri yetersiz
|
||||
|
||||
“Garanti” yerine mümkün olduğunda “daha güvenli” ifadesi tercih edilir.
|
||||
|
||||
### Tercih uyumu
|
||||
|
||||
Program, sihirbaz seçimleriyle karşılaştırılır. Uyum tek bir kapalı puan olarak
|
||||
verilmek yerine anlaşılır gerekçelerle açıklanır.
|
||||
|
||||
Örnek olumlu sinyaller:
|
||||
|
||||
- İlgi alanlarınla uyumlu
|
||||
- Tercih ettiğin şehirlerden birinde
|
||||
- Devlet/vakıf tercihine uyuyor
|
||||
- Kariyer önceliklerinle örtüşüyor
|
||||
|
||||
Örnek çelişki sinyalleri:
|
||||
|
||||
- Seçtiğin ilgi alanlarının dışında görünüyor
|
||||
- Tercih ettiğin şehirlerin dışında
|
||||
- Üniversite türü tercihinle uyuşmuyor
|
||||
- Belirttiğin önceliklerle zayıf eşleşiyor
|
||||
|
||||
Dil yargılayıcı olmamalıdır. “Sana uygun değil” yerine “seçimlerinle
|
||||
karşılaştırdığımızda şu noktada ayrışıyor” denir.
|
||||
|
||||
## Liste ekranı
|
||||
|
||||
Liste yalnızca seçilen programları depolayan bir favoriler alanı değildir.
|
||||
Kullanıcının tercih stratejisini görünür kılan karar merkezidir.
|
||||
|
||||
Her satırda en az şu bilgiler bulunur:
|
||||
|
||||
- Program ve üniversite
|
||||
- Güncel taban sıralaması
|
||||
- Kullanıcının sıralamasına göre risk durumu
|
||||
- Tercihlerle uyumlu noktalar
|
||||
- Varsa çelişki veya dikkat notu
|
||||
- Listeden çıkarma eylemi
|
||||
|
||||
Örnek uyumlu satır mesajı:
|
||||
|
||||
> İlgi alanın ve devlet üniversitesi tercihinle uyumlu. Sıralama açısından
|
||||
> dengeli aralıkta.
|
||||
|
||||
Örnek çelişkili satır mesajı:
|
||||
|
||||
> Bu program listende kalabilir; ancak seçtiğin ilgi alanlarının ve tercih
|
||||
> ettiğin şehirlerin dışında görünüyor.
|
||||
|
||||
Örnek risk mesajı:
|
||||
|
||||
> Geçen yılın taban sıralaması senin sıralamandan daha yukarıda. Hayal
|
||||
> tercihlerinden biri olarak değerlendirebilirsin.
|
||||
|
||||
Birden fazla çelişki varsa sistem hepsini aynı anda bağırmaz. En önemli bir veya
|
||||
iki gerekçe satırda gösterilir; ayrıntılar açılır alanda sunulur.
|
||||
|
||||
## İlerleme hissi
|
||||
|
||||
Deneyimin oyunlaştırma döngüsü şöyledir:
|
||||
|
||||
1. **Keşfet:** Sıralamana göre programları incele.
|
||||
2. **Seç:** `+` ile ilgini çeken programı listene al.
|
||||
3. **Anla:** Sistem risk ve tercih uyumunu açıklar.
|
||||
4. **Dengele:** Hayal, dengeli ve daha güvenli dağılımını geliştir.
|
||||
5. **Tamamla:** Gerekçeli 24 tercihlik listeye ulaş.
|
||||
|
||||
İlerleme göstergeleri:
|
||||
|
||||
- `3 / 24 tercih`
|
||||
- Hayal / dengeli / daha güvenli dağılımı
|
||||
- Tercihlerle güçlü uyum gösteren program sayısı
|
||||
- Dikkat edilmesi gereken seçim sayısı
|
||||
- Listenin eksik kalan tarafına yönelik tek ve uygulanabilir öneri
|
||||
|
||||
Örnek yönlendirmeler:
|
||||
|
||||
> Listen dengeli tercihlerde güçleniyor. Birkaç daha güvenli seçenek eklemek
|
||||
> riski dağıtabilir.
|
||||
|
||||
> Seçtiklerinin çoğu aynı şehirde. Şehir konusunda esneksen alternatiflerini
|
||||
> genişletebilirsin.
|
||||
|
||||
> 24 tercihe ulaştın. Şimdi dağılımı ve dikkat notlarını birlikte gözden geçir.
|
||||
|
||||
## `+` düğmesinin durumları
|
||||
|
||||
- **Varsayılan:** “Listeme ekle”
|
||||
- **Sihirbaz gerekli:** Tıklama sihirbaz ön bilgilendirmesini açar
|
||||
- **Ekleniyor:** Düğme geçici olarak devre dışı kalır
|
||||
- **Eklendi:** `+` yerine onay işareti gösterilir, erişilebilir etiketi
|
||||
“Listende” olur
|
||||
- **Liste dolu:** Düğme devre dışıdır ve “Listen 24 tercihe ulaştı” açıklaması
|
||||
sunulur
|
||||
- **Hata:** Seçim kaybolmaz; kullanıcıya yeniden deneme eylemi verilir
|
||||
|
||||
İkon düğmesinin dokunma alanı en az 44×44 piksel olmalı ve yalnızca ikona bağlı
|
||||
anlam bırakılmamalıdır. Görsel etiket veya erişilebilir ad bulunmalıdır.
|
||||
|
||||
## Sihirbaz seçimlerini değiştirme
|
||||
|
||||
Kullanıcı sihirbaz yanıtlarını daha sonra değiştirebilir. Değişiklik mevcut
|
||||
programları listeden otomatik olarak çıkarmaz. Bütün satırların uyum
|
||||
değerlendirmesi yeni yanıtlara göre yeniden hesaplanır ve değişen yorumlar
|
||||
görünür biçimde güncellenir.
|
||||
|
||||
Örnek bildirim:
|
||||
|
||||
> Tercihlerin güncellendi. Listendeki programları yeni seçimlerine göre yeniden
|
||||
> değerlendirdik; hiçbir programı silmedik.
|
||||
|
||||
## Kaçınılacak kalıplar
|
||||
|
||||
- Kullanıcıyı sihirbazı doldurmadığı için suçlayan dil
|
||||
- Uyumsuz bir programın eklenmesini engellemek
|
||||
- Sadece renk ile uyum veya risk anlatmak
|
||||
- Kesin yerleşme vaadi vermek
|
||||
- Her `+` tıklamasında modal veya onay adımı göstermek
|
||||
- Rozet, puan ve seri gibi kararın ciddiyetini oyunlaştıran ödüller
|
||||
- Kullanıcının sihirbazdan önce tıkladığı programı unutmak
|
||||
- İlgi alanı uyumunu yerleşme ihtimaliyle aynı şeymiş gibi sunmak
|
||||
|
||||
## Başarı ölçütleri
|
||||
|
||||
- Sıralama sonucundan ilk `+` tıklamasına geçiş
|
||||
- İlk `+` sonrasında sihirbaz tamamlama oranı
|
||||
- Sihirbazdan sonra bekleyen programın başarıyla eklenme oranı
|
||||
- Kullanıcı başına eklenen program sayısı
|
||||
- 24 tercihe ulaşan kullanıcı oranı
|
||||
- Uyarı görüldükten sonra programı koruma/çıkarma davranışı
|
||||
- Sihirbaz tercihlerini güncelleme oranı
|
||||
- Liste dağılımının zaman içinde daha dengeli hâle gelmesi
|
||||
|
||||
Bu metrikler kullanıcıyı daha çok tıklamaya zorlamak için değil, daha bilinçli
|
||||
bir tercih listesi kurup kuramadığını anlamak için kullanılmalıdır.
|
||||
101
UX-DUZELTMELER.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# UX/CRO Kritik Düzeltmeler — Uygulama Takibi
|
||||
|
||||
UX denetiminden çıkan 🔴 kritik bulguların uygulama listesi.
|
||||
Kaynak: 26 Temmuz 2026 tarihli UX/CRO denetimi.
|
||||
|
||||
## K1 — Ödeme sonrası teslimat
|
||||
|
||||
- [x] `/odeme/sonuc` başarı CTA'sı doğrudan `/listem`'e gitsin (ölü `/sonuc?acildi=1` yerine)
|
||||
(sahte "paid" siparişle canlı doğrulandı: CTA → `/listem?acildi=1`)
|
||||
- [x] `/listem` ödeme dönüşünde tek seferlik "kilit açıldı" deneyimi (banner + unblur)
|
||||
- [x] Ücretli `/listem` başlık kopyası düzelsin (rozet "Paketin aktif", alt metin
|
||||
"24 tercihinin tamamını gerekçe, risk analizi ve trendleriyle…")
|
||||
|
||||
## K2 — Buton dürüstlüğü (giriş duvarı sürprizi)
|
||||
|
||||
- [x] Hero sihirbazı son butonu girişsiz kullanıcıda girişi açıkça söylesin
|
||||
("Giriş yap ve listeni gör"; girişliyse "Listemi oluştur (3 kredi)")
|
||||
- [x] Hero akışı oturumu açık kullanıcıyı `/giris`'ten sektirmeyip doğrudan `/sonuc`'a götürsün
|
||||
- [x] `/sonuc` sihirbazında girişsiz son buton "Listemi gör" yerine dürüst etiket taşısın
|
||||
- [x] Değer önce: hero sihirbazı biten girişsiz kullanıcı `/giris`'e değil doğrudan
|
||||
`/sonuc`'taki ücretsiz tabloya gitsin; AI CTA'sı oradan "5 deneme kredinle
|
||||
AI listeni kur — giriş yap" olarak verilsin (panel + sabit alt kart);
|
||||
girişten dönüşte kayıtlı seçimlerle otomatik üretim başlasın
|
||||
|
||||
## K3 — Fiyat şeffaflığı
|
||||
|
||||
- [x] Landing hero mikro-kopyasına paket fiyatı (299 TL) eklensin
|
||||
- [x] FAQ "Fiyatlandırma nasıl çalışıyor?" cevabına rakamlar yazılsın
|
||||
|
||||
## K4 — Puan türü seçici
|
||||
|
||||
- [x] Hero formuna SAY/EA/SÖZ/DİL/TYT segment kontrolü (varsayılan SAY)
|
||||
|
||||
## K5 — Ücretsiz kullanıcıya AI sohbeti
|
||||
|
||||
- [x] `/listem`'de paketi olmayan kullanıcıya kalan kredileriyle sohbet açılsın
|
||||
(fiyat kartının altında; mesaj gönderimi + kredi düşümü canlı doğrulandı)
|
||||
- [x] Kredi bitince composer yerinde paket CTA'sı görünsün (0 krediyle canlı doğrulandı)
|
||||
|
||||
## K6 — Ödeme/AI hata mesajları
|
||||
|
||||
- [x] iyzico/Anthropic yapılandırma hataları kullanıcıya ham sızmasın (log'a detay, kullanıcıya sade mesaj)
|
||||
(iyzico yolu canlı doğrulandı: "Ödeme şu anda başlatılamıyor; kartından çekim yapılmadı…")
|
||||
- [x] `/paket` sayfası `?hata=token|siparis` parametresini okuyup banner göstersin
|
||||
|
||||
## Bonus
|
||||
|
||||
- [x] Hero rozetindeki "açıkk" yazım hatası düzeltilsin
|
||||
|
||||
---
|
||||
|
||||
# 🟠 Önemli
|
||||
|
||||
- [x] Ö1: `/listem` paywall ara kartı kopyası netleşsin (kilit ikonu + "aşağıdaki tüm
|
||||
satırlar açık" çelişkisi giderilsin; CTA fiyatı söylesin)
|
||||
(yeni kopya: "İlk 3 tercihte AI analizini gördün… Analizleri aç — 299 TL")
|
||||
- [x] Ö2: İl seçimi mobilde aranabilir liste ile yapılabilsin; harita mobilde geri
|
||||
çekilsin; harita illerine erişilebilir isim (aria-label) eklensin
|
||||
(arama + çip birincil; harita ≥sm'de görsel destek; path'lerde aria-label/aria-pressed)
|
||||
- [x] Ö3: "Listem" isim çakışması giderilsin (manuel liste "Seçtiklerim" olsun,
|
||||
AI raporu /listem "Listem" kalsın)
|
||||
- [x] Ö3b: Navbar'daki "Seçtiklerim" butonu liste boşken görünmesin — tabloya
|
||||
ulaşmamış ziyaretçiye "0/24" gürültü; ilk program eklenince belirir,
|
||||
liste boşalınca kaybolur (canlı doğrulandı)
|
||||
- [x] Ö4: Güven sayfaları eklensin (gizlilik/KVKK, kullanım & iade koşulları,
|
||||
iletişim) ve footer + giriş + paket sayfalarından bağlansın
|
||||
(NOT: metinler MVP taslağı — yayın öncesi hukuki gözden geçirme gerekir)
|
||||
- [x] Ö5: AI'ın ürettiği genel değerlendirme ve uyarılar /listem'de görünsün
|
||||
(paketliye tam, paketsize kilitli önizleme — "Danışman özeti" kartı)
|
||||
- [x] Ö6: Paketlinin gerçek revizyon akışı /listem'de çalışsın (geri bildirim
|
||||
kutusu; başlıktaki "Revize et" oraya götürsün)
|
||||
(`revizyon-kutusu.tsx` → `listeRevize` aksiyonu; kalan hak sayacıyla)
|
||||
- [x] Ö7: Liste tepesine dilim özeti (hayal/dengeli/garanti dağılımı) ve tek
|
||||
şehir uyarısı eklensin
|
||||
- [x] Ö8: 2024/2025 verisi eksik satırda çelişkili trend rozeti gösterilmesin
|
||||
(rozet iki yıl da doluysa çıkar; yoksa "Veri eksik")
|
||||
- [x] Ö9: Magic link "gönderildi" ekranına yeniden gönder + e-postayı düzelt eklensin
|
||||
(30 sn bekleme sayaçlı yeniden gönder + "E-postayı düzelt")
|
||||
- [x] Ö10: Mobilde sohbete hızlı erişim (yüzen "Danışmana sor" kısayolu)
|
||||
|
||||
# 🛠 Dev araçları
|
||||
|
||||
- [x] Dev süperadmin paneli: yalnızca geliştirme ortamında sol altta "DEV"
|
||||
butonu — anında giriş (magic link atlanır), kredi/paket/rapor senaryoları,
|
||||
sahte "paid" siparişle ödeme başarı ekranı, tüm sayfalara hızlı bağlantılar
|
||||
(`src/components/dev/dev-panel.tsx` + `src/lib/dev/actions.ts`;
|
||||
layout NODE_ENV kontrolüyle monte eder, aksiyonlar sunucuda ayrıca korunur)
|
||||
|
||||
# 🟢 Güzel olur
|
||||
|
||||
- [x] G1: Sıralama girişinde canlı binlik ayracı + toast yerine input altı hata
|
||||
- [x] G2: Sihirbaz adım göstergesi tamamlanan adımı işaretlesin; 1. adımda
|
||||
"Geri" görünmesin
|
||||
- [x] G3: Route-level loading / error / not-found boundary'leri eklensin
|
||||
(kök loading/error/not-found + /sonuc ve /listem'e Skeleton'lı loading)
|
||||
- [x] G4: Landing istatistik kartlarının yanında "yerleşme garantisi vermeyen
|
||||
dürüst araç" konumlandırması cesur işlensin (koyu kart: "Yerleşme
|
||||
garantisi vermiyoruz. Çünkü kimse veremez.")
|
||||
- [x] G5: `sonButonEtiketi` şeffaflığı hero varyantına taşınsın (girişli:
|
||||
"Listemi oluştur (3 kredi)"; girişsiz artık ücretsiz tabloya gittiği
|
||||
için "Ücretsiz tablonu gör")
|
||||
@@ -22,6 +22,7 @@
|
||||
"hooks": "@/hooks"
|
||||
},
|
||||
"registries": {
|
||||
"@skiper-ui": "https://skiper-ui.com/registry/{name}.json"
|
||||
"@skiper-ui": "https://skiper-ui.com/registry/{name}.json",
|
||||
"@magicui": "https://magicui.design/r/{name}"
|
||||
}
|
||||
}
|
||||
|
||||
32
content/rehber/devlet-mi-vakif-mi.md
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
baslik: Devlet mi Vakıf mı? Burslu ve İndirimli Programlar Nasıl Okunur?
|
||||
aciklama: Aynı bölümün beş farklı fiyat etiketi var — %100 burslu, %50 indirimli, ücretli... Vakıf tablosunu doğru okumanın ve devletle kıyaslamanın rehberi.
|
||||
tarih: 2026-07-19
|
||||
---
|
||||
|
||||
Tercih tablolarında aynı bölümün adı beş kez geçebilir: *Psikoloji (Burslu)*, *Psikoloji (%50 İndirimli)*, *Psikoloji (%25 İndirimli)*, *Psikoloji (Ücretli)*, *Psikoloji (İngilizce)*. Bunlar ayrı programlardır: ayrı kontenjan, ayrı taban, ayrı fiyat. Bu yazı tabloyu doğru okumayı ve devlet-vakıf kararını sağlıklı vermeyi anlatıyor.
|
||||
|
||||
## Varyantlar ne anlama geliyor?
|
||||
|
||||
- **Burslu (%100):** Öğrenim ücreti yok. Vakıfların vitrini olduğu için tabanı çoğu zaman aynı üniversitenin ücretli programından *yüz binlerce sıra* daha iyidir; köklü devletlerle yarışır.
|
||||
- **%50 / %25 indirimli:** Ücretin o oranı düşülür. Kalan tutar yıllara ve okula göre ciddi bir bütçedir; 4-6 yıllık toplam maliyeti baştan hesapla.
|
||||
- **Ücretli:** Tam ücret. Tabanlar genelde en geniştir.
|
||||
- **İngilizce / UOLP:** Öğretim dili veya ortak program bilgisidir; burs bilgisi değildir. Hazırlık yılı ekleyebilir.
|
||||
|
||||
Kritik uyarı: **bursun sürme koşullarını** üniversitenin kendi yönetmeliğinden kontrol et. Çoğu vakıfta giriş bursu süresizdir ama bazı okullarda not ortalaması şartı vardır.
|
||||
|
||||
## Devlet-vakıf kararında gerçek kriterler
|
||||
|
||||
**Bütçe dışında** şunlara bak:
|
||||
|
||||
1. **Kadro ve bölümün kurumsallığı.** Bölümün öğretim üyesi sayısı, araştırma çıktısı, akreditasyonu (MÜDEK, PSİKOLOG odaklı akreditasyonlar vb.) devlet-vakıf etiketinden daha belirleyicidir.
|
||||
2. **Şehir ve yaşam maliyeti.** Devlet okulu + büyükşehir kirası, bazen vakıf burslusu + yurt kombinasyonundan pahalıya gelir. Toplam maliyeti karşılaştır.
|
||||
3. **Tabanın söylediği.** Bir vakıf burslusunun tabanı köklü devletlerle aynıysa, piyasa o programa devlet muadili değer biçiyor demektir. [İşletme](/bolum/isletme) veya [Psikoloji](/bolum/psikoloji) tablolarını aç; Tür kolonunda devlet/vakıf ayrımını, satır altlarında burs varyantlarını yan yana görüp kendi sıralamanla kıyaslayabilirsin.
|
||||
|
||||
## Listede nasıl konumlanır?
|
||||
|
||||
- Burslu vakıf programları taban olarak "hayal/dengeli" bölgene düşüyorsa devlet alternatifleriyle **aynı blokta, istek sırana göre** diz — ayrı kefeye koyma.
|
||||
- İndirimli programlarda aileyle net bütçe konuşmasını *listeyi vermeden önce* yap; yerleştikten sonra "ödeyemeyiz" durumu bir yıl kaybettirir.
|
||||
- Ücretli programı yalnızca bütçe gerçekten uygunsa ve o okulu gerçekten istiyorsan yaz — "garanti olsun" diye yazılan ücretli program, kayıt yaptırmayacaksan [ölü tercihten](/rehber/olu-tercih-nedir) beterdir: yerleşirsen ek tercih hakkın da yanar.
|
||||
|
||||
Sıralamana hangi devlet ve vakıf programlarının düştüğünü tek ekranda görmek için [tercih robotuna](/tercih-robotu) sıralamanı gir; devlet/vakıf filtresiyle iki evreni ayrı ayrı da tarayabilirsin.
|
||||
40
content/rehber/ek-yerlestirme-2026.md
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
baslik: Ek Yerleştirme Nedir? 2026 Ek Tercih Rehberi
|
||||
aciklama: İlk yerleştirmede boşta kaldıysan oyun bitmedi — ek yerleştirmenin kuralları, kimlerin başvurabileceği ve ikinci şansı doğru kullanmanın yolu.
|
||||
tarih: 2026-07-22
|
||||
---
|
||||
|
||||
Merkezi yerleştirme sonuçları açıklandığında bir programa yerleşememiş olmak yılın sonu değildir. Üniversiteler kayıt dönemini kapattığında binlerce kontenjan boş kalır ve ÖSYM bu boş kontenjanlar için **ek yerleştirme** (ek tercih) süreci açar.
|
||||
|
||||
## Ek yerleştirme ne zaman?
|
||||
|
||||
Kayıtlar tamamlandıktan sonra, genellikle **Eylül ayı içinde**. ÖSYM önce boş kontenjanları içeren Ek Yerleştirme Kılavuzu'nu yayımlar, ardından birkaç günlük tercih penceresi açılır. Kesin tarihler her yıl ÖSYM duyurusuyla netleşir — tercih takviminin tamamı için [YKS 2026 tercih takvimi](/rehber/yks-tercih-takvimi-2026) yazısına bak.
|
||||
|
||||
## Kimler başvurabilir?
|
||||
|
||||
Kurallar nettir ve en kritik olanı şudur:
|
||||
|
||||
- **İlk yerleştirmede herhangi bir programa yerleşen aday, kayıt yaptırmasa bile ek yerleştirmeye başvuramaz.** "Yerleştim ama gitmeyeceğim, ek tercihte daha iyisini denerim" diye bir yol yoktur.
|
||||
- Ek yerleştirme yalnızca ilk yerleştirmede **hiçbir programa yerleşememiş** adaylara açıktır.
|
||||
- İlk dönemde hiç tercih yapmamış adaylar da ek yerleştirmeye katılabilir.
|
||||
|
||||
Bu kural, ilk listenin sonuna "kayıt yaptırmayacağım ama boşta da kalmayayım" mantığıyla program yazmanın neden tehlikeli olduğunu gösterir: oraya yerleşirsen ek tercih hakkın yanar. Bu tuzağın detayı [tercih listesi rehberinde](/rehber/tercih-listesi-nasil-yapilir).
|
||||
|
||||
## Ek yerleştirmede taban nasıl işler?
|
||||
|
||||
Ek yerleştirmede bir programa başvurabilmek için o programın **ilk yerleştirmedeki taban puanına eşit veya daha yüksek** puana sahip olman gerekir (ilk yerleştirmede hiç dolmayan programlarda bu şart esner). Yani ek tercih "tabanlar sıfırlanır, herkes her yere yazılır" demek değildir.
|
||||
|
||||
## Boş kontenjanlar nereden çıkar?
|
||||
|
||||
- İlk yerleştirmede hiç dolmayan programlar (çoğunlukla vakıf ücretli ve bazı önlisans programları),
|
||||
- Yerleşip kayıt yaptırmayan adaylardan boşalan yerler.
|
||||
|
||||
Boş kontenjan listesi ağırlıklı olarak vakıf üniversiteleri, ücretli/indirimli varyantlar ve önlisans programlarından oluşur; ama her yıl devlet üniversitelerinden de şaşırtıcı fırsatlar çıkar. Hangi bölümlerde kontenjanların geniş olduğuna dair fikir edinmek için [tüm bölümlerin taban puanları](/bolumler) sayfasındaki kontenjan kolonlarına göz at.
|
||||
|
||||
## Ek tercih stratejisi
|
||||
|
||||
1. **Kılavuzu bekleme, hazırlığını şimdi yap.** Sıralamana uygun program evrenini [tercih robotuyla](/tercih-robotu) önceden çıkar; kılavuz yayımlanınca sadece kesişimi almak kalır.
|
||||
2. **İlk yerleştirme mantığıyla kurma.** Ek yerleştirmede tek liste hakkın var ve pencere kısa; dengeli-garanti ağırlıklı, gerçekçi bir liste kur.
|
||||
3. **Kayıt yaptırmayacağın programı yine yazma.** Aynı kural burada da geçerli — ek yerleştirmeden sonra üçüncü bir şans yok.
|
||||
|
||||
Ek yerleştirme, ilk turda şanssızlık yaşayanlar için gerçek bir ikinci şanstır; panik turu değil. Veriyle ve soğukkanlı kurulmuş bir ek liste, aceleyle yazılmış ilk listeden daha iyi sonuç verebilir.
|
||||
41
content/rehber/kac-siralama-ile-hangi-bolume-girebilirim.md
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
baslik: Kaç Sıralama ile Hangi Bölüme Girebilirim? (2025 Verileriyle)
|
||||
aciklama: 10 binden 1 milyona — sıralama bandına göre hangi bölümlerin gerçekçi olduğunun veriye dayalı haritası.
|
||||
tarih: 2026-07-23
|
||||
---
|
||||
|
||||
"Sıralamam X, nereyi kazanırım?" tercih döneminin en çok sorulan sorusu. Aşağıdaki bantlar 2025 YKS yerleştirme verilerine (YÖK Atlas) dayanır ve **kabaca bir harita** çizer — kesin sınır değildir; aynı bölümün tabanı üniversiteye, şehre ve burs durumuna göre çok geniş bir aralığa yayılır.
|
||||
|
||||
## Sayısal (SAY) için kaba harita
|
||||
|
||||
| Sıralama bandı | Gerçekçi seçenekler |
|
||||
| --- | --- |
|
||||
| İlk 5 bin | Köklü devletlerde [Tıp](/bolum/tip), [Bilgisayar Mühendisliği](/bolum/bilgisayar-muhendisligi), [Elektrik-Elektronik Mühendisliği](/bolum/elektrik-elektronik-muhendisligi) |
|
||||
| 5-25 bin | Devlet tıp (yeni fakülteler), [Diş Hekimliği](/bolum/dis-hekimligi), iyi devletlerde mühendislikler |
|
||||
| 25-75 bin | [Eczacılık](/bolum/eczacilik), devlet mühendislikleri, [Mimarlık](/bolum/mimarlik) |
|
||||
| 75-200 bin | Sağlık bilimleri ([Fizyoterapi ve Rehabilitasyon](/bolum/fizyoterapi-ve-rehabilitasyon), [Hemşirelik](/bolum/hemsirelik)), Anadolu devletlerinde mühendislik |
|
||||
| 200-500 bin | Fen bilimleri, ziraat, daha geniş kapatan mühendislikler, vakıf burslu seçenekleri |
|
||||
| 500 bin+ | Açıköğretim dışı seçenekler daralır; önlisans (TYT) tarafı güçlü alternatif olur |
|
||||
|
||||
## Eşit Ağırlık (EA) için kaba harita
|
||||
|
||||
| Sıralama bandı | Gerçekçi seçenekler |
|
||||
| --- | --- |
|
||||
| İlk 10 bin | Köklü devletlerde [Hukuk](/bolum/hukuk), [Psikoloji](/bolum/psikoloji) |
|
||||
| 10-50 bin | Devlet hukuk (geniş kapatanlar), [İşletme](/bolum/isletme) / [İktisat](/bolum/iktisat) (iyi devletler), Psikoloji |
|
||||
| 50-150 bin | Anadolu devletlerinde İİBF bölümleri, [Rehberlik ve Psikolojik Danışmanlık](/bolum/rehberlik-ve-psikolojik-danismanlik) |
|
||||
| 150-400 bin | Vakıf burslu/indirimli seçenekler, sosyal hizmet, kamu yönetimi |
|
||||
|
||||
Sözel ve Dil tarafında bantlar daha da geniştir; öğretmenlikler için ayrıca **başarı sıralaması şartı** devreye girer — detayı [Baraj ve başarı sıralaması şartları](/rehber/siralama-sartlari-2026) yazısında.
|
||||
|
||||
## Bu tabloyu nasıl kullanmalısın?
|
||||
|
||||
1. **Bandını bul, ama banda güvenme.** Bant sana "hangi bölümlere bakmaya değer" der; hangi üniversitede tutacağını söylemez. Aynı bölüm içinde tabanlar 10 kat oynayabilir.
|
||||
2. **Bölüm sayfasının tablosuna in.** Örneğin [Psikoloji taban puanları](/bolum/psikoloji) sayfasında 380'e yakın programın tek tek tabanını görürsün — senin sıralaman listenin neresine düşüyorsa gerçekçi bölgen orasıdır.
|
||||
3. **Kendi sıralamanla tara.** [Tercih robotuna](/tercih-robotu) sıralamanı gir; robot 23.000+ programın içinden senin bandına düşenleri hayal/dengeli/garanti dilimleriyle ayırıp önüne koyar. Tablo ezberlemekten hızlıdır.
|
||||
|
||||
## Unutma
|
||||
|
||||
- Sıralaman **puan türüne özeldir**; SAY sıralaman ile EA sıralaman farklıdır, her listeyi kendi türünün sıralamasıyla kur.
|
||||
- Burslu/indirimli/İngilizce varyantların tabanları aynı bölümde bile çok farklıdır.
|
||||
- 2026 tabanları bu yılın yerleştirmesiyle netleşir; buradaki veriler pusula, garanti değil.
|
||||
50
content/rehber/merkezi-yerlestirme-nasil-calisir.md
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
baslik: Merkezi Yerleştirme Nasıl Çalışır? ÖSYM Seni Nasıl Yerleştirir?
|
||||
aciklama: "Üst sıraya yazarsam şansımı yakar mıyım?" korkusunun cevabı sistemin kendisinde. ÖSYM'nin yerleştirme mantığı, tek şemada ve öğrenci diliyle.
|
||||
tarih: 2026-07-26
|
||||
---
|
||||
|
||||
Tercih döneminin en çok aranan sorularından biri şu: *"Tercihler nasıl değerlendiriliyor? Üst sıraya iddialı bir bölüm yazarsam alttaki şansımı kaybeder miyim?"* Kısa cevap: **hayır, kaybetmezsin.** Nedenini anlamak için ÖSYM'nin yerleştirme mantığını bir kez görmek yeter — sistem sandığından çok daha basit çalışır.
|
||||
|
||||
## Sistem tek cümlede
|
||||
|
||||
ÖSYM önce **adayları** puana göre sıralar, sonra sıra sana gelince **senin listeni** yukarıdan aşağı okur ve boş kontenjan bulduğu ilk satıra seni yerleştirir. Hepsi bu.
|
||||
|
||||
```mermaid
|
||||
%% aria: Merkezi yerleştirme akış şeması: ÖSYM tüm adayları puana göre sıralar ve sıra puanı yüksekten düşüğe ilerler; sıra sana gelince tercih listen birinci satırdan başlayarak kontrol edilir, boş kontenjan bulunan ilk programa yerleşirsin ve alttaki satırlara hiç bakılmaz; 24 satırın hiçbirinde yer yoksa boşta kalırsın ama ek yerleştirme hakkın devam eder.
|
||||
%% altyazi: Sistem listene her zaman yukarıdan aşağı bakar; bir satıra yerleştiğin an alttaki satırlar devre dışı kalır.
|
||||
flowchart TD
|
||||
P("ÖSYM tüm adayları puana göre sıralar<br/>sıra, puanı yüksekten düşüğe ilerler") --> S("Sıra sana geldi:<br/>listen 1. satırdan okunmaya başlar")
|
||||
S --> T1{"1. tercihinde boş<br/>kontenjan var mı?"}
|
||||
T1 -- "evet" --> Y("Yerleştin<br/>alttaki satırlara hiç bakılmaz")
|
||||
T1 -- "hayır" --> T2{"2. tercihinde<br/>boş yer var mı?"}
|
||||
T2 -- "evet" --> Y
|
||||
T2 -- "hayır" --> D("aynı soru 24. satıra<br/>kadar tekrarlanır")
|
||||
D --> B{"24 satırın hiçbirinde<br/>yer kalmadı mı?"}
|
||||
B -- "boşta kaldın" --> E("Üzülme, bitmedi:<br/>ek yerleştirme hakkın saklı")
|
||||
|
||||
classDef garanti fill:#d1fae5,stroke:#10b981,color:#065f46
|
||||
classDef uyari fill:#fef3c7,stroke:#f59e0b,color:#92400e
|
||||
class Y garanti
|
||||
class E uyari
|
||||
```
|
||||
|
||||
## Bu mantıktan çıkan üç altın kural
|
||||
|
||||
**1) Üst sıradaki "hayal" tercihi alttakilere zarar veremez.** Sistem 1. tercihinde yer bulamazsa hiç duraksamadan 2.'ye geçer. Hayal bölümünü en üste yazmanın tek "maliyeti" bir satırdır; alttaki dengeli ve garanti tercihlerinin ihtimali kılını bile kıpırdatmaz. Bu yüzden listenin başı gönlüne göre, sonu aklına göre kurulur — dilim mantığının tamamı [tercih listesi rehberinde](/rehber/tercih-listesi-nasil-yapilir) var.
|
||||
|
||||
**2) Yerleştiğin satırın altı yok hükmündedir.** 3. tercihine yerleştiysen 4-24 arası hiç okunmaz. Bu yüzden listeyi *yerleşme ihtimaline göre değil, istek sırana göre* dizmelisin: en çok istediğin hep daha üstte durmalı. "Daha çok istediğim bölüm alttaydı, keşke" cümlesinin telafisi yoktur.
|
||||
|
||||
**3) Taban sıralaması yerleştirme bittikten sonra oluşur.** Bir programın tabanı, o programa **yerleşen son kişinin** sıralamasıdır. Yani tabanlar önceden ilan edilen bir eşik değil, o yılın adaylarının tercih davranışının sonucudur — bu yüzden yıldan yıla oynar. Detayı [tabanlar nasıl değişir](/rehber/taban-siralamalar-nasil-degisir) yazısında.
|
||||
|
||||
## Peki neden hâlâ "ölü tercih" diye bir şey var?
|
||||
|
||||
Sistemin yukarıdan aşağı okuması, sıralamanın çok üstünde kapatan bir programı listenin *sonuna* yazmayı anlamsızlaştırır: o satıra sıra geldiyse zaten üstteki 20 satırda yer bulamamışsındır; tabanı senden çok iyi olan o program sana hiç açılmayacaktır. Bu satırlar listede yer kaplayan boş kurşunlardır — tanımı ve temizleme yöntemi için [ölü tercih nedir](/rehber/olu-tercih-nedir) yazısına bak.
|
||||
|
||||
## Pratik sonuç
|
||||
|
||||
- Listenin başına puanın "yetmeyecek gibi" duran ama çok istediğin programları çekinmeden yaz.
|
||||
- Ortayı sıralamana yakın programlarla doldur, sona gerçekten razı olacağın garantileri koy.
|
||||
- Sıralamanla hangi dilime neyin girdiğini görmek için [tercih robotuna](/tercih-robotu) sıralamanı girmen yeterli.
|
||||
|
||||
Sistemi bilen aday, listeyi korkuyla değil stratejiyle kurar. Korku listesi hep aşağı yığılır; strateji listesi yukarıdan kazanır.
|
||||
47
content/rehber/obp-nedir-nasil-hesaplanir.md
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
baslik: OBP Nedir, Nasıl Hesaplanır? Diploma Notu Kaç Puan Getirir?
|
||||
aciklama: Ortaöğretim başarı puanının hesabı, yerleştirme puanına gerçek katkısı ve "geçen yıl yerleştiysen çarpan yarıya düşer" kuralı — sayılarla ve tek şemada.
|
||||
tarih: 2026-07-27
|
||||
---
|
||||
|
||||
Tercih döneminde en çok aranan hesap sorusu: *"Diploma notum yerleştirme puanıma kaç puan ekler?"* Cevap net bir formüle dayanır ve iki dakikada öğrenilir. Ama formülün ucunda, tercih stratejini doğrudan etkileyen bir kural saklı: **geçen yıl bir programa yerleşenlerin katkısı yarıya düşer.**
|
||||
|
||||
## Hesap üç adımda
|
||||
|
||||
Lise diploma notun 50-100 arasındadır. ÖSYM bunu 5 ile çarpar ve **OBP** (Ortaöğretim Başarı Puanı) 250-500 arasında bir değere dönüşür. Yerleştirme puanına eklenen katkı ise OBP'nin 0,12 ile çarpımıdır:
|
||||
|
||||
```mermaid
|
||||
%% aria: OBP hesap şeması: 50 ile 100 arasındaki diploma notu 5 ile çarpılarak 250 ile 500 arasında OBP değerine dönüşür; OBP 0,12 ile çarpılarak 30 ile 60 puan arasında bir katkı üretir ve ham YKS puanına eklenerek yerleştirme puanını oluşturur; geçen yıl merkezi yerleştirmeyle bir programa yerleştiysen çarpan 0,06'ya düşer ve katkı 15 ile 30 puan arasına iner.
|
||||
%% altyazi: Katkı aralığı 30-60 puandır; iki aday arasındaki gerçek fark ise çoğu zaman birkaç puandır çünkü herkes en az 30 alır.
|
||||
flowchart TD
|
||||
D("Diploma notun<br/>50 ile 100 arası") -- "5 ile çarpılır" --> O("OBP<br/>250 ile 500 arası")
|
||||
O -- "0,12 ile çarpılır" --> K("Yerleştirme puanına katkı<br/>30 ile 60 puan arası")
|
||||
K --> P("Ham YKS puanın + katkı<br/>= yerleştirme puanın")
|
||||
O -. "geçen yıl bir programa yerleştiysen<br/>çarpan 0,06 olur" .-> Z("Katkı yarıya düşer<br/>15 ile 30 puan arası")
|
||||
|
||||
classDef garanti fill:#d1fae5,stroke:#10b981,color:#065f46
|
||||
classDef hayal fill:#fee2e2,stroke:#ef4444,color:#991b1b
|
||||
class P garanti
|
||||
class Z hayal
|
||||
```
|
||||
|
||||
## Sayının doğru okuması: 60 değil, fark önemli
|
||||
|
||||
"60 puana kadar katkı" kulağa devasa gelir ama herkes **en az 30** alır (diploma notu 50 bile olsa). Yani seninle rakibin arasındaki gerçek OBP farkı en fazla 30 puandır ve diploma notları yakınsa bu fark birkaç puana iner. Diploma notu 85 olan bir aday 51 puan katkı alır; 95 olan 57 alır — arada sadece 6 puan vardır. OBP kimseyi tek başına bölüm atlatmaz; **eşit puan bölgesinde sıralamayı birkaç bin kaydırır.** Sıralamanın puandan neden daha önemli olduğu ayrı bir yazının konusu: [taban puan mı, sıralama mı?](/rehber/taban-puan-mi-siralama-mi)
|
||||
|
||||
## Kritik kural: çarpan neden yarıya düşer?
|
||||
|
||||
Geçen yıl merkezi yerleştirmeyle bir programa **yerleştirildiysen** — kayıt yaptırmamış olsan bile — bu yıl OBP çarpanın 0,12 yerine **0,06** uygulanır (kontenjansız açıköğretim programları bu kuralın dışındadır). Yani "bir yere yerleşeyim de garantim olsun, seneye yine denerim" planının görünmez bir bedeli vardır: gelecek yılki puanından 15-30 puan peşinen gider.
|
||||
|
||||
Bunun tercih listene çevirisi şudur: **yerleşsen bile gitmeyeceğin programı listene yazma.** Bu kuralın diğer bedelleriyle birlikte tamamı [tercih listesi rehberinde](/rehber/tercih-listesi-nasil-yapilir) anlatılıyor.
|
||||
|
||||
## Okul birincilerine ayrı kapı
|
||||
|
||||
Okul birincileri için üniversitelerde **ayrı bir kontenjan** ayrılır (2026'da yaklaşık 17 bin 862 kişilik). Okul birincisi, hem genel kontenjandan hem de okul birincisi kontenjanından değerlendirilir — hangisinden yerleşirse o geçerli olur. Ayrıca 2026'da şehit ve gazi yakınları ile 34 yaş üstü kadın adaylar için de özel kontenjanlar var; sonuç belgende bu kontenjanlardan birine hakkın görünüyorsa tercih ekranında ayrıca işaretlemeyi unutma.
|
||||
|
||||
## Özet
|
||||
|
||||
- OBP = diploma notu × 5; katkı = OBP × 0,12 → **30-60 puan arası.**
|
||||
- Herkes en az 30 aldığı için gerçek rekabet farkı küçüktür; asıl belirleyici sınav performansın ve sıralamandır.
|
||||
- Geçen yıl yerleştiysen çarpan yarıya düşer — istemediğin programı listeye yazmanın en somut cezası budur.
|
||||
- Sıralamanla nereye uzanabildiğini görmek için [tercih robotunu](/tercih-robotu) kullanabilirsin.
|
||||
33
content/rehber/olu-tercih-nedir.md
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
baslik: Ölü Tercih Nedir, Nasıl Anlaşılır? (Ve Nasıl Kaçınılır)
|
||||
aciklama: Listende hiç işe yaramayan satırlar olabilir. Ölü tercihin tanımı, en sık yapılan iki biçimi ve listeni bu tuzaktan temizlemenin yolu.
|
||||
tarih: 2026-07-24
|
||||
---
|
||||
|
||||
Ölü tercih, **hiçbir senaryoda seni yerleştirmeyecek satır** demektir. Listende durur, yer kaplar ama hiç işe yaramaz. 24 tercih hakkın varken bunun 5-6'sını ölü satırlara harcamak, tercih dönemi hatalarının en sessizidir — kimse fark etmez, ta ki sonuçlar açıklanana kadar.
|
||||
|
||||
## Ölü tercihin iki biçimi
|
||||
|
||||
**1) Sıralaması yetmeyecek programı listenin sonuna yazmak.**
|
||||
ÖSYM yerleştirme sistemi listeni yukarıdan aşağı okur ve seni *yerleşebildiğin en üst tercihe* koyar. Diyelim sıralaman 200 bin ve 15. sıraya tabanı 40 bin kapatan bir program yazdın. O programa yerleşebilmen için üstteki 14 tercihin de tutmaması VE tabanın 40 binden 200 bine gevşemesi gerekir — pratikte imkânsız. O satır ölüdür. Hayal tercihi meşrudur ama yeri listenin **başıdır**, sonu değil.
|
||||
|
||||
**2) Zaten üstte yazdığın programın kopyasını alta yazmak.**
|
||||
Aynı programın ikinci yazımı sistemde hiçbir şey değiştirmez. Benzer şekilde, tabanı üstteki tercihten belirgin şekilde daha iyi olan bir programı alta koymak da ölüdür: üstteki tutmadıysa alttaki hiç tutmaz.
|
||||
|
||||
## Nasıl anlarsın?
|
||||
|
||||
Her satır için şu soruyu sor: **"Bu programa yerleşmem için üstümdeki tercihlerin hepsinin tutmaması VE bu programın tabanının benim sıralamama gelmesi gerçekçi mi?"**
|
||||
|
||||
Pratik kontrol yöntemi:
|
||||
|
||||
- Satırın taban sıralamasına son 4 yıl üzerinden bak (tek yıl yanıltır).
|
||||
- Tabanı, senin sıralamandan iyiyse → o satır ancak listenin *üst bloğunda* (hayal) anlamlıdır.
|
||||
- Tabanı üstündeki satırdan da iyiyse → sıra hatası var; satırları taban gevşekliğine göre yeniden diz.
|
||||
|
||||
[Tercih robotuna](/tercih-robotu) sıralamanı girdiğinde programlar hayal/dengeli/garanti dilimleriyle etiketlenir; bir programın senin sıralamana göre hangi bölgede olduğunu tek bakışta görürsün. Popüler bölümlerde tabanların ne kadar geniş bir aralığa yayıldığını görmek için [Psikoloji](/bolum/psikoloji) veya [Hukuk](/bolum/hukuk) tablolarına bak — aynı bölümün tabanı üniversiteye göre yüz binlerce sıra oynayabilir; yani bölüm ölü değildir, *yanlış üniversite-satır eşleşmesi* ölüdür.
|
||||
|
||||
## Ölü tercihten temizlenmiş liste nasıl görünür?
|
||||
|
||||
Yukarıdan aşağı **tabanlar giderek gevşer**. İlk satırlar "tutarsa harika", orta blok "büyük ihtimal buradayım", son satırlar "kesin tutar ve severek giderim" der. Grafiğe döksen düzgün bir merdiven görürsün; ölü tercihli listelerde merdivenin ortasında yukarı fırlayan basamaklar olur.
|
||||
|
||||
Son bir uyarı: ölü tercihi temizleyeyim derken listenin başındaki hayal tercihlerini de kesme. Üst sıradaki iddialı tercih ölü değildir — bedava piyango biletidir. Ölü olan, o iddialı tercihi listenin *sonuna* saklamaktır.
|
||||
32
content/rehber/onlisans-mi-lisans-mi.md
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
baslik: TYT ile Önlisans Tercihi — Önlisans mı, Lisans mı?
|
||||
aciklama: 2 yıllıklar "yedek plan" değil, başlı başına bir rota. Önlisansın avantajları, DGS köprüsü ve TYT sıralamasıyla akıllı tercih kurmanın yolu.
|
||||
tarih: 2026-07-17
|
||||
---
|
||||
|
||||
AYT'si istediği gibi gitmeyen ya da hedefi zaten uygulamalı bir meslek olan aday için önlisans (2 yıllık) programlar güçlü bir rotadır. Türkiye'deki yükseköğretim kontenjanının büyük bölümü TYT puan türüyle öğrenci alan önlisans programlarındadır — yani seçenek evreni geniştir.
|
||||
|
||||
## Önlisans ne zaman doğru tercih?
|
||||
|
||||
- **Hedef meslek uygulamalıysa.** [Bilgisayar Programcılığı](/bolum/bilgisayar-programciligi), [Anestezi](/bolum/anestezi), [İlk ve Acil Yardım](/bolum/ilk-ve-acil-yardim) gibi programlar 2 yılda alana özgü istihdama bağlanır.
|
||||
- **Lisansa köprü olarak.** DGS (Dikey Geçiş Sınavı) ile önlisans mezunları ilgili lisans bölümlerine geçebilir. "TYT'm iyi, AYT'm zayıf" profili için 2+ yıl planı — önlisans + DGS — düşük sıralamayla doğrudan zayıf bir lisansa gitmekten daha iyi sonuç verebilir.
|
||||
- **Bir yıl daha sınav istemiyorsan.** Tekrar hazırlanmak yerine alanda ilerlemek isteyene zaman kazandırır.
|
||||
|
||||
## Lisans lehine düşünmen gereken durumlar
|
||||
|
||||
- Hedef meslek lisans diploması şart koşuyorsa (mühendislik, hukuk, tıp, öğretmenlik...).
|
||||
- Sıralaman, gitmekten mutlu olacağın bir lisans programına yetiyorsa — sırf "üniversite kazandı" demek için istemediğin lisansa gitmek de, gereksiz yere önlisansa razı olmak da hatadır. Bandını görmek için [kaç sıralama ile hangi bölüme girebilirim](/rehber/kac-siralama-ile-hangi-bolume-girebilirim) rehberine bak.
|
||||
|
||||
## TYT tablosunu doğru okumak
|
||||
|
||||
Önlisans tercihinde üç ayrıntı belirleyicidir:
|
||||
|
||||
1. **Sıralama TYT sıralamasıdır.** SAY/EA sıralamanla önlisans tablosu okuma; sonuç belgende TYT satırı ayrı yazar.
|
||||
2. **Aynı programın tabanı okula göre uçurum yapar.** Büyükşehirdeki köklü bir MYO'nun programı ile küçük ilçe MYO'sunun aynı adlı programı arasında yüz binlerce sıra fark olabilir — [Bilgisayar Programcılığı tablosunda](/bolum/bilgisayar-programciligi) bunu net görürsün (395 program!).
|
||||
3. **DGS planın varsa bölüm adına dikkat.** DGS'de hangi önlisanstan hangi lisansa geçilebildiği tablolarla sınırlıdır; hedef lisansı önce belirle, ona köprü olan önlisansı sonra seç.
|
||||
|
||||
## Tercih listesi taktiği
|
||||
|
||||
24 tercih hakkı lisans ve önlisansta **ortaktır** — aynı listeye ikisini de yazabilirsin. Ama farklı puan türlerinin sıralamaları karışacağı için düzeni şöyle kur: önce gitmeye razı olduğun lisans programları (kendi türünün sıralamasıyla), sonra önlisans bloğu (TYT sıralamasıyla). Her iki blokta da [ölü tercih](/rehber/olu-tercih-nedir) kuralları aynen geçerli.
|
||||
|
||||
TYT sıralamanı [tercih robotuna](/tercih-robotu) girip türü "TYT" seçersen önlisans evrenini hayal/dengeli/garanti dilimleriyle görürsün; lisans sıralamanla da ayrı bir tarama yapıp iki listeyi yan yana koyman en sağlıklısı.
|
||||
40
content/rehber/siralama-sartlari-2026.md
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
baslik: Baraj ve Başarı Sıralaması Şartları 2026 (Tıp, Hukuk, Mühendislik, Öğretmenlik...)
|
||||
aciklama: Bazı bölümleri istemek yetmez — YÖK'ün koyduğu başarı sıralaması şartını geçmek gerekir. Hangi bölümde hangi eşik var, tek tabloda.
|
||||
tarih: 2026-07-18
|
||||
---
|
||||
|
||||
Bazı bölümler için puanın ve sıralaman "yetiyor" görünse bile, YÖK'ün belirlediği **başarı sıralaması şartını** sağlamıyorsan o bölümü tercih bile edemezsin. Bu şart taban sıralamasından farklıdır: taban, yerleşen son kişinin sıralamasıdır ve her yıl piyasada oluşur; **sıralama şartı** ise merkezî bir üst eşiktir — geçemeyen listeye yazamaz.
|
||||
|
||||
## 2026'da sıralama şartı olan başlıca bölümler
|
||||
|
||||
| Bölüm | Puan türü | Sıralama şartı |
|
||||
| --- | --- | --- |
|
||||
| [Tıp](/bolum/tip) | SAY | İlk 50 bin |
|
||||
| [Hukuk](/bolum/hukuk) | EA | İlk 100 bin |
|
||||
| [Diş Hekimliği](/bolum/dis-hekimligi) | SAY | İlk 80 bin |
|
||||
| [Eczacılık](/bolum/eczacilik) | SAY | İlk 100 bin |
|
||||
| Mühendislik programları (ör. [Bilgisayar Mühendisliği](/bolum/bilgisayar-muhendisligi)) | SAY | İlk 300 bin |
|
||||
| [Mimarlık](/bolum/mimarlik) | SAY | İlk 250 bin |
|
||||
| Öğretmenlik programları (ör. [İlköğretim Matematik Öğretmenliği](/bolum/ilkogretim-matematik-ogretmenligi)) | İlgili tür | İlk 300 bin |
|
||||
|
||||
Şartlar kılavuzla kesinleşir; tercih vermeden önce mutlaka ÖSYM kılavuzunun güncel maddesinden doğrula. (Eşikler son yıllarda sabit seyrediyor ama nihai söz her yıl kılavuzundur.)
|
||||
|
||||
## Sıralama şartı ile taban sıralaması karışmasın
|
||||
|
||||
İki örnekle netleşir:
|
||||
|
||||
- Sıralaman SAY 45 bin olsun. Tıp için şartı (ilk 50 bin) **geçiyorsun** — tercih edebilirsin. Ama köklü devlet tıp fakültelerinin tabanı ilk 5-15 bin bandında kapanır; senin gerçekçi tıp evrenin tabanı 45 bine yakın olan fakültelerdir. Şartı geçmek yerleşmeyi garanti etmez.
|
||||
- Sıralaman EA 130 bin olsun. Hukuk şartı ilk 100 bin olduğundan hukuk programlarını **hiç tercih edemezsin** — tabanı 130 binden geniş bir hukuk fakültesi olsa bile. Bu durumda enerjini şartı olmayan komşu bölümlere ([Kamu Yönetimi](/bolum/kamu-yonetimi), [Sosyal Hizmet](/bolum/sosyal-hizmet) vb.) yönlendirmek daha akıllıca.
|
||||
|
||||
## Baraj puanları
|
||||
|
||||
Sıralama şartından ayrı olarak tercih yapabilmek için puan türünde **baraj puanını** aşmış olman gerekir (TYT ve ilgili yerleştirme puanı barajları). Sonuç belgende puanın hesaplandıysa bu barajı geçmişsin demektir; ayrıca dert etme.
|
||||
|
||||
## Ne yapmalı?
|
||||
|
||||
1. Hedef bölümünün şartı var mı, kılavuzdan işaretle.
|
||||
2. Şartı geçiyorsan gözünü tabana çevir: bölüm sayfasındaki tabloda ([örnek: Tıp](/bolum/tip)) kendi sıralamanın düştüğü bandı bul.
|
||||
3. Şartı geçemiyorsan o bölümü listeden çıkar ve alternatif rotayı kur — [tercih robotu](/tercih-robotu) sıralamana uygun programları zaten şartlara göre süzülmüş tablolar üzerinden gösterir.
|
||||
|
||||
Sıralama şartı acımasız görünür ama işlevi nettir: hem kontenjan enflasyonunu hem de "nasılsa yazayım" kalabalığını engeller. Senin işin, şartı geçtiğin bölümlerde tabanı doğru okumak.
|
||||
33
content/rehber/taban-puan-mi-siralama-mi.md
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
baslik: Taban Puan mı, Başarı Sıralaması mı? Tercihte Hangisine Bakılır?
|
||||
aciklama: İki sayı da sonuç belgende yazıyor ama tercih listeni sadece biriyle kurmalısın. Neden sıralamanın kazandığının kısa ve net açıklaması.
|
||||
tarih: 2026-07-21
|
||||
---
|
||||
|
||||
Kısa cevap: **başarı sıralamasına bakılır.** Taban puan, tabelada büyük yazan ama seni yanıltan sayıdır. Nedenini iki dakikada anlatalım.
|
||||
|
||||
## Puan neden yanıltır?
|
||||
|
||||
YKS puanı, sınavın o yılki zorluğuna ve aday kitlesinin performansına göre şekillenir. Sınav kolay geçtiyse herkesin puanı şişer; zor geçtiyse söner. 450 puan bir yıl ilk 30 bine, ertesi yıl ilk 60 bine denk gelebilir. Yani "geçen yıl bu bölüm 450 ile kapatmış, benim puanım 455, güvendeyim" cümlesi hatalıdır — iki farklı yılın puanları aynı cetvelle ölçülmez.
|
||||
|
||||
## Sıralama neden güvenilir?
|
||||
|
||||
Başarı sıralaması, seni o yıl sınava giren herkesle kıyaslar: "SAY'da 85.000'incisin" bilgisi yıldan yıla **karşılaştırılabilir** kalır. Bir programın geçen yılki taban *sıralaması* 90 bin ise, bu yıl 85 bininci aday için o program "dengeli" bölgededir — sınav kolay muydu zor muydu fark etmez, çünkü herkes aynı gemide.
|
||||
|
||||
ÖSYM sonuç belgende her puan türü için ayrı sıralama yazar. Tercih listeni hangi türden kuruyorsan **o türün sıralamasını** kullan; SAY sıralamanla EA listesi kurmak elma-armut kıyasıdır.
|
||||
|
||||
## Peki taban puan ne işe yarar?
|
||||
|
||||
- Aynı yıl içinde iki programı kabaca kıyaslamaya,
|
||||
- Ek yerleştirmede başvuru eşiği olarak (ek tercihte ilk yerleştirme taban puanı şart koşulur — detay [ek yerleştirme rehberinde](/rehber/ek-yerlestirme-2026)),
|
||||
- Bir de haber sitelerine manşet olmaya.
|
||||
|
||||
Liste kurarken açtığın her tabloda gözün **sıralama kolonunda** olmalı. Örneğin [Bilgisayar Mühendisliği taban puanları](/bolum/bilgisayar-muhendisligi) sayfasında programlar taban sıralamasına göre dizilir; puan kolonu yalnızca bağlam içindir. Aynısı [Hukuk](/bolum/hukuk) ve tüm diğer bölüm sayfaları için geçerli.
|
||||
|
||||
## Uygulamada üç kural
|
||||
|
||||
1. **Listeyi sıralamayla kur.** Her satırın son 3-4 yıllık taban sıralaması trendine bak; tek yıl yanıltır ([neden yanılttığını burada gösterdik](/rehber/taban-siralamalar-nasil-degisir)).
|
||||
2. **Puan haberlerine kapılma.** "X bölümü 500 puanla öğrenci aldı" manşeti sana hiçbir şey söylemez; o yılın 500 puanı kaçıncı sıraysa bilgi odur.
|
||||
3. **Sıralamanı doğru yerden oku.** ÖSYM sonuç belgesindeki, kendi puan türünün "başarı sırası" satırı. OBP eklenmiş/eklenmemiş karışıklığına dikkat — tercihte kullanılan, yerleştirme puanına ait sıralamadır.
|
||||
|
||||
Sıralamanı biliyorsan gerisi mekanik: [tercih robotuna](/tercih-robotu) gir, sıralamana uygun programları hayal/dengeli/garanti dilimleriyle gör, listeni veriyle kur.
|
||||
39
content/rehber/taban-siralamalar-nasil-degisir.md
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
baslik: Taban Sıralamalar Yıldan Yıla Ne Kadar Değişir?
|
||||
aciklama: "Geçen yıl 90 bin kapatmış, ben 85 binim, garanti" demeden önce oku — tabanları oynatan beş mekanizma ve trend okumanın doğru yolu.
|
||||
tarih: 2026-07-16
|
||||
---
|
||||
|
||||
Tercih listeni geçen yılın tabanlarıyla kuruyorsun ama yerleşmeni **bu yılın** tabanları belirleyecek. Aradaki fark bazen birkaç bin, bazen yüz binlerce sıra. Bu yazı tabanları neyin oynattığını ve trendi nasıl okuyacağını anlatıyor.
|
||||
|
||||
## Tabanı oynatan mekanizmalar
|
||||
|
||||
**1) Kontenjan değişimi.** En mekanik etki: bir program kontenjanını 60'tan 90'a çıkarırsa taban gevşer; 90'dan 60'a inerse sıkılaşır. Bölüm sayfalarındaki kontenjan kolonunu yıllar arasında kıyaslamak bu yüzden önemli.
|
||||
|
||||
**2) Aday davranışı (sürü etkisi).** "Geçen yıl çok kapattı" diye herkes bir programdan kaçarsa taban gevşer; "gevşedi" diye ertesi yıl herkes geri dönerse tekrar sıkılaşır. Tabanlar bu yüzden testere dişi gibi salınabilir — tek yıla bakan, testere dişinin tepesinden ya da dibinden ölçüm alır.
|
||||
|
||||
**3) Yeni açılan programlar.** Bir şehirde yeni fakülte açılınca hem kendi tabanı belirsiz olur hem çevresindeki programların tabanını seyreltir.
|
||||
|
||||
**4) Şartlar ve politika değişiklikleri.** Başarı sıralaması şartının gelmesi/eşiğin değişmesi, burs oranlarının değişmesi, öğretim dilinin değişmesi tabanı sıçratır. ([Şartların güncel listesi burada.](/rehber/siralama-sartlari-2026))
|
||||
|
||||
**5) Ekonomi ve istihdam algısı.** Mezun istihdamına dair haber akışı bile birkaç yıl içinde bir bölümün talebini görünür şekilde değiştirir — son yıllarda kimi mühendisliklerde ve sağlık programlarında bunun örnekleri yaşandı.
|
||||
|
||||
## Trend nasıl okunur?
|
||||
|
||||
Tek yılın tabanı **fotoğraf**, dört yılın tabanı **film**dir. Film izle:
|
||||
|
||||
- **İstikrarlı taban** (dört yıl üst üste dar bantta): güvenilir referans. Sıralaman tabana yakınsa "dengeli", belirgin gerisindeyse "garanti" davranabilirsin.
|
||||
- **Tek yönlü trend** (her yıl sıkılaşıyor): geçen yılın tabanına güvenme; bu yıl daha da sıkılaşacağını varsayıp payla yaklaş. Popüler bölümlerde sık görülür — [Psikoloji](/bolum/psikoloji) ve [Bilgisayar Mühendisliği](/bolum/bilgisayar-muhendisligi) tablolarında 2024-2025 kolonlarını yan yana koyup bak.
|
||||
- **Testere dişi** (bir sıkı bir gevşek): sürü etkisi işliyor demektir; ortalamayı referans al, uç yıla değil.
|
||||
- **Veri boşluğu** (bazı yıllar "—"): yeni ya da o yıl dolmamış program; belirsizlik yüksek, listende dengeli değil garanti bölgesine koyma, hayal bölgesine koy.
|
||||
|
||||
Bölüm sayfalarımızdaki tablolarda 2025 sıralamasının yanında 2024 kolonu ve değişim yönü işareti (▲/▼) tam bu iş için var.
|
||||
|
||||
## Listeye nasıl yansıtılır?
|
||||
|
||||
1. Her satır için son 4 yılın tabanına bak; tek yıl asla yeterli değil.
|
||||
2. Sıkılaşma trendindeki programları bir kademe yukarı say ("dengeli" sandığın aslında "hayal" olabilir).
|
||||
3. Gevşeme trendindeki programlara erken sevinme; sürü geri dönebilir.
|
||||
4. Belirsizliği [dengeli bir listeyle](/rehber/tercih-listesi-nasil-yapilir) yönet: trend ne yaparsa yapsın, hayal/dengeli/garanti dağılımı düzgün kurulmuş bir liste boşta bırakmaz.
|
||||
|
||||
[Tercih robotu](/tercih-robotu) bu analizi senin yerine yapar: sıralamanı girdiğinde programları yalnızca son tabana göre değil, çok yıllı veriyle dilimleyerek gösterir.
|
||||
36
content/rehber/tercih-listesi-nasil-yapilir.md
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
baslik: YKS Tercih Listesi Nasıl Yapılır? (2026 Rehberi)
|
||||
aciklama: 24 tercihlik listeyi dilim dilim kurmanın adım adım yöntemi — hangi tercihi kaçıncı sıraya, neden yazacağını bilerek.
|
||||
tarih: 2026-07-25
|
||||
---
|
||||
|
||||
Tercih listesi kurmanın tek doğru yolu yok; ama boşta bırakan yanlış yolları belli. Bu rehber, ÖSYM'nin tanıdığı 24 tercih hakkını **hayal / dengeli / garanti** mantığıyla nasıl dağıtacağını anlatıyor.
|
||||
|
||||
## Önce ölçüyü düzelt: puan değil, sıralama
|
||||
|
||||
Tercihin tek sağlam ölçüsü **başarı sıralamandır**. Puanlar her yıl sınavın zorluğuna göre kayar; aynı puan bir yıl 80 bininci, ertesi yıl 120 bininci sıraya denk gelebilir. ÖSYM sonuç belgende her puan türü için ayrı sıralaman yazar — listeyi o satıra göre kur. Bu konunun detayı için [Taban puan mı, başarı sıralaması mı?](/rehber/taban-puan-mi-siralama-mi) yazısına bak.
|
||||
|
||||
## Listenin üç bölgesi
|
||||
|
||||
**1) Hayal tercihleri (ilk 4-8 sıra).** Taban sıralaması seninkinden *daha iyi* kapatan ama çok istediğin programlar. "Sıralamam yetmez, boşa gider" korkusu yersizdir: bir programı üst sıraya yazmak, alttaki tercihlere yerleşme ihtimalini **azaltmaz**. ÖSYM sistemi yukarıdan aşağı bakar; hayal tutmazsa sıradakine geçer. Tabanlar her yıl oynar — geçen yıl 5 bin kapatmış bir bölüm bu yıl 8 bine gevşeyebilir.
|
||||
|
||||
**2) Dengeli tercihler (orta blok, 8-12 sıra).** Taban sıralaması senin sıralamana yakın programlar. Listenin kalbi burasıdır; yerleşme ihtimalinin en yüksek olduğu bölge. Aynı bölümün farklı şehirlerdeki/üniversitelerdeki versiyonlarını sıralama sırasıyla diz.
|
||||
|
||||
**3) Garanti tercihleri (son 4-6 sıra).** Taban sıralaması seninkinden belirgin şekilde geniş programlar. Buradaki altın kural: **yerleşsen kayıt yaptırmayacağın hiçbir programı yazma.** Garanti dilimi "razı olacağın en makul seçenek" demektir, "ne olursa olsun bir yere gireyim" demek değil. Kayıt yaptırmayacağın bir yere yerleşirsen hem bir yılın gider hem de ek yerleştirmeye başvuramazsın.
|
||||
|
||||
## Sık yapılan hatalar
|
||||
|
||||
- **Tek yıla bakmak.** 2025 tabanı tek başına yanıltır; en az son 3-4 yılın trendine bak. Tabanların yıldan yıla nasıl oynadığını [Taban sıralamalar yıldan yıla ne kadar değişir?](/rehber/taban-siralamalar-nasil-degisir) yazısında verilerle gösterdik.
|
||||
- **24'ü doldurmak için doldurmak.** Okumayacağın bölümü listeye eklemek hata; 16 gerçekçi tercih, 24 gelişigüzel tercihten iyidir.
|
||||
- **"Ölü tercih" yazmak.** Tabanı senin sıralamandan çok daha iyi olan bir programı listenin *sonlarına* yazmak o satırı çöpe atar — üstteki tercihlerinden birine yerleşmişsen oraya sıra zaten gelmez. Detay: [Ölü tercih nedir?](/rehber/olu-tercih-nedir)
|
||||
- **Sadece bölüme ya da sadece şehre kilitlenmek.** "Ne olursa olsun [Tıp](/bolum/tip)" diyorsan 24 tercihi de tıp yazabilirsin; ama "mühendislik olsun da hangisi olursa olsun" diyorsan [Bilgisayar Mühendisliği](/bolum/bilgisayar-muhendisligi), [Elektrik-Elektronik Mühendisliği](/bolum/elektrik-elektronik-muhendisligi) gibi yakın bölümleri karışık ve sıralama sırasıyla dizmek daha akıllıca.
|
||||
|
||||
## Pratik akış
|
||||
|
||||
1. Sıralamanı ve puan türünü not et.
|
||||
2. Sıralamana uygun program evrenini çıkar — [tercih robotuna](/tercih-robotu) sıralamanı girerek hayal/dengeli/garanti dilimlerini saniyede görebilirsin.
|
||||
3. İstemediklerini ele, kalanları *istek sırana* göre diz (yerleşme ihtimaline göre değil).
|
||||
4. Son kontrol: listenin başı hayal mi, ortası dengeli mi, sonu gerçekten garanti mi? Sonunda kayıt yaptırmayacağın program var mı?
|
||||
5. ÖSYM AİS'e girerken listeyi bir kez daha kod kod doğrula.
|
||||
|
||||
Listeyi kurarken her satırın "neden burada" sorusuna cevabı olmalı. Cevabı yoksa o satır ya yanlış yerde ya da listede fazla.
|
||||
59
content/rehber/universite-kayit-rehberi-2026.md
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
baslik: Üniversite Kaydı Nasıl Yapılır? 2026 e-Kayıt ve Belge Rehberi
|
||||
aciklama: Yerleştin, tebrikler — şimdi kaydını kaçırma. e-Devlet'ten 5 dakikada e-kayıt, şahsen kayıtta istenen belgeler ve "kayıt yaptırmazsam ne olur" sorusunun net cevabı.
|
||||
tarih: 2026-07-28
|
||||
---
|
||||
|
||||
Yerleştirme sonuçları açıklandıktan sonra en çok aranan soru değişir: "nereye yerleştim"in yerini **"kayıt nasıl yapılır, son gün ne zaman?"** alır. 2026'da kayıtlar **24-28 Ağustos** tarihleri arasında; e-Devlet üzerinden elektronik kayıt ise **24-26 Ağustos** günlerinde yapılabiliyor. Takvimin tamamı için [2026 tercih takvimi](/rehber/yks-tercih-takvimi-2026) yazısına bakabilirsin.
|
||||
|
||||
## Önce e-kayıt dene: belge yok, yol yok, sıra yok
|
||||
|
||||
Üniversitelerin büyük bölümü e-Devlet üzerinden **e-kayıt** kabul ediyor. e-Devlet'e girip *"Üniversite E-Kayıt"* hizmetini açtığında yerleştiğin program listeleniyorsa birkaç onayla kaydın tamamlanır — diploma, fotoğraf, şehirlerarası yolculuk gerekmez. Kayıt belgeni yine e-Devlet'ten barkodlu indirebilirsin.
|
||||
|
||||
```mermaid
|
||||
%% aria: Üniversite kayıt akış şeması: bir programa yerleştikten sonra kayıt yaptırmaya karar verirsen önce e-Devlet'te e-kayıt seçeneğini kontrol edersin; açıksa 24-26 Ağustos arasında belgesiz ve sırasız e-kayıt yaparsın, kapalıysa 24-28 Ağustos arasında belgelerinle üniversiteye giderek şahsen kayıt olursun; iki yol da kaydını tamamlar. Kayıt yaptırmazsan bu yılki hakkın yanar, yerleştiğin için ek yerleştirmeye giremezsin ve gelecek yıl OBP katkın yarıya düşer.
|
||||
%% altyazi: e-kayıt penceresi şahsen kayıttan iki gün önce kapanır; önce e-kaydı dene, olmuyorsa belgelerle yola çık.
|
||||
flowchart TD
|
||||
S("Sonuçlar açıklandı:<br/>bir programa yerleştin") --> K{"Kayıt yaptıracak mısın?"}
|
||||
K -- "evet" --> E{"e-Devlet'te e-kayıt<br/>seçeneğin açık mı?"}
|
||||
E -- "evet" --> E1("24-26 Ağustos: e-kayıt<br/>belge yok, sıra yok, 5 dakika")
|
||||
E -- "hayır" --> E2("24-28 Ağustos: üniversitede şahsen kayıt<br/>belgelerini yanına al")
|
||||
E1 --> T("Kaydın tamam,<br/>artık öğrencisin")
|
||||
E2 --> T
|
||||
K -- "hayır" --> R("Bu yılki hakkın yanar:<br/>ek yerleştirmeye giremezsin,<br/>gelecek yıl OBP katkın yarıya düşer")
|
||||
|
||||
classDef garanti fill:#d1fae5,stroke:#10b981,color:#065f46
|
||||
classDef hayal fill:#fee2e2,stroke:#ef4444,color:#991b1b
|
||||
class T garanti
|
||||
class R hayal
|
||||
```
|
||||
|
||||
## Şahsen kayıtta istenen belgeler
|
||||
|
||||
Üniversiteler kendi listesini yayımlar; standart çekirdek şudur:
|
||||
|
||||
- **Lise diploması** (aslı) ya da yeni mezunlar için mezuniyet belgesi
|
||||
- **ÖSYS yerleştirme sonuç belgesi** (internet çıktısı yeterli)
|
||||
- Nüfus cüzdanı / T.C. kimlik kartı ve fotokopisi
|
||||
- Vesikalık fotoğraf (genelde 4-6 adet)
|
||||
- Bazı programlar için ek koşul belgeleri: sağlık raporu, boy-kilo şartı, mülakat sonucu gibi — bunlar kılavuzda programın yanındaki koşul numaralarında yazar
|
||||
|
||||
İkinci öğretim ya da vakıf programına yerleştiysen ilk taksit/öğrenim ücreti dekontu da istenir. Gitmeden önce üniversitenin kayıt sayfasını mutlaka aç; eksik belge, kayıt döneminin en klasik zaman kaybıdır.
|
||||
|
||||
## "Kayıt yaptırmazsam ne olur?"
|
||||
|
||||
Bu sorunun cevabı üç maddedir ve üçü de önemlidir:
|
||||
|
||||
1. **Bu yılki hakkın yanar.** Yerleştiğin programa sonradan "vazgeçtim, geleyim" diyemezsin.
|
||||
2. **Ek yerleştirmeye giremezsin.** Kayıt yaptırmasan bile *yerleştirilmiş* sayılırsın ve [ek yerleştirme](/rehber/ek-yerlestirme-2026) kapısı sana kapanır.
|
||||
3. **Gelecek yıl OBP çarpanın yarıya düşer.** Seneye tekrar sınava girersen diploma notu katkın 0,12 yerine 0,06 ile hesaplanır — [OBP yazısında](/rehber/obp-nedir-nasil-hesaplanir) sayılarla anlattık.
|
||||
|
||||
Bu üç maddenin tek bir tercih dersi var: **kayıt yaptırmayacağın programı listene hiç yazma.** Liste kurarken bu süzgeci nasıl uygulayacağın [tercih listesi rehberinde](/rehber/tercih-listesi-nasil-yapilir).
|
||||
|
||||
## Kayıt sonrası küçük ama önemli işler
|
||||
|
||||
- Ders kaydı / oryantasyon tarihlerini üniversitenin öğrenci işleri sayfasından not al; kayıt olmak çoğu üniversitede ders seçimini otomatik yapmaz.
|
||||
- Yurt başvurusu (KYK) ayrı bir takvimle yürür — kayıt haftasını beklemeden başvuru dönemini takip et.
|
||||
- Öğrenci belgeni e-Devlet'ten alabilirsin; indirim ve burs başvurularının çoğu bunu ister.
|
||||
|
||||
Yerleşmek maratonun bitişi, kayıt ise ipi göğüslemek. Son güne bırakma — e-kayıt penceresi, şahsen kayıttan **iki gün önce** kapanıyor.
|
||||
55
content/rehber/yerlesemedim-ne-yapmaliyim.md
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
baslik: Yerleşemedim ya da İstemediğim Bölüme Yerleştim — Şimdi Ne Olacak?
|
||||
aciklama: Sonuç ekranı istediğin gibi çıkmadıysa önünde hâlâ üç yol var: ek yerleştirme, yatay geçiş ve yeniden deneme. Hangi durumda hangisi mantıklı, tek şemada.
|
||||
tarih: 2026-08-01
|
||||
---
|
||||
|
||||
Sonuçlar açıklandığında iki tür hayal kırıklığı yaşanır: hiçbir tercihe yerleşememek ya da listenin sonlarındaki "keşke yazmasaydım" satırına yerleşmek. İkisi de yolun sonu değil — ama ikisinin kuralları **birbirinden çok farklı** ve yanlış hamle, doğru kapıyı kapatabiliyor.
|
||||
|
||||
## Önce durumunu netleştir
|
||||
|
||||
```mermaid
|
||||
%% aria: Yerleşememe durumunda karar şeması: sonuç ekranında hiçbir tercihe yerleşemediysen ek yerleştirmeye başvurabilirsin ve boş kontenjanlar için yeni bir 24 tercihlik liste yaparsın; istemediğin bir programa yerleştiysen iki yol vardır: kayıt yaptırırsan birinci sınıfta merkezi yerleştirme puanınla yatay geçiş kapısını araştırabilirsin, kayıt yaptırmazsan yerleşmiş sayıldığın için ek yerleştirmeye giremezsin ve kalan tek yol gelecek yıl yeniden sınava girmektir.
|
||||
%% altyazi: Kritik ayrım: "yerleşemedim" ek yerleştirme kapısını açar; "yerleştim ama gitmedim" o kapıyı kapatır.
|
||||
flowchart TD
|
||||
S{"Sonuç ekranında<br/>ne yazıyor?"}
|
||||
S -- "hiçbir tercihe yerleşemedin" --> E("Ek yerleştirme hakkın var:<br/>boş kontenjanlar için yeni bir liste")
|
||||
E --> E2("Eylülde ÖSYM kılavuzu yayımlar,<br/>yeniden 24 tercih yaparsın")
|
||||
S -- "istemediğin bir programa yerleştin" --> K{"Kayıt yaptıracak mısın?"}
|
||||
K -- "evet" --> Y("Kayıt ol; 1. sınıfta merkezi puanla<br/>yatay geçiş kapısını araştır")
|
||||
K -- "hayır" --> R("Yerleşmiş sayılırsın:<br/>ek yerleştirmeye giremezsin,<br/>kalan yol gelecek yıl yeniden YKS")
|
||||
|
||||
classDef uyari fill:#fef3c7,stroke:#f59e0b,color:#92400e
|
||||
classDef garanti fill:#d1fae5,stroke:#10b981,color:#065f46
|
||||
classDef hayal fill:#fee2e2,stroke:#ef4444,color:#991b1b
|
||||
class E,E2 uyari
|
||||
class Y garanti
|
||||
class R hayal
|
||||
```
|
||||
|
||||
## Yol 1: Ek yerleştirme — boşta kalanların ikinci şansı
|
||||
|
||||
İlk yerleştirmede **hiçbir programa yerleşemediysen** ek yerleştirmeye başvurabilirsin. Kayıt dönemi bitince boş kalan ve kayıt yaptırılmadığı için boşalan kontenjanlar ÖSYM'nin ek kılavuzunda ilan edilir; yeniden en fazla 24 tercih yaparsın. Tabanlar ilk yerleştirmeye göre genelde gevşer ama en çok istenen programlar ek yerleştirmeye nadiren kalır. Kimin başvurabileceği, takvimi ve stratejisiyle tüm detaylar [ek yerleştirme rehberinde](/rehber/ek-yerlestirme-2026).
|
||||
|
||||
Kritik kural bir kez daha: bir programa **yerleştirildiysen** — kayıt yaptırmamış olsan bile — ek yerleştirme sana kapalıdır. "İstemediğim yere yerleştim, kayıt olmayayım, ek tercihte daha iyisini yazarım" planı **çalışmaz.**
|
||||
|
||||
## Yol 2: Kayıt ol + yatay geçişi araştır
|
||||
|
||||
İstemediğin programa yerleştiysen çoğu durumda en az riskli hamle **kayıt olmaktır.** Çünkü kayıtlı öğrenciye açık bir kapı var: **merkezi yerleştirme puanıyla (Ek Madde-1) yatay geçiş.** Mantığı şu:
|
||||
|
||||
- YKS'de aldığın puan, yerleştiğin yıl için geçerliliğini korur.
|
||||
- Puanın, geçmek istediğin programın **senin yerleştiğin yıldaki** taban puanına eşit ya da ondan yüksekse başvurabilirsin.
|
||||
- Başvuru, yerleştiğin yıl içinde değil, öğrenimin başladıktan sonraki dönemlerde (üniversitelerin ilan ettiği kontenjan ve takvimle) yapılır ve bu hak **bir kez** kullanılır.
|
||||
|
||||
Yani "puanım aslında X bölümüne yetiyordu ama listeme yazmamıştım" durumundaysan, bir dönem/yıl sonra o bölüme sınavsız geçme ihtimalin var. Kontenjanlar sınırlı ve üniversiteden üniversiteye değişir; hedef üniversitenin yatay geçiş sayfasını şimdiden takibe al.
|
||||
|
||||
## Yol 3: Yeniden denemek — bedelini bilerek
|
||||
|
||||
Gelecek yıl tekrar sınava girmek meşru bir plan; ama iki bedelini baştan bil:
|
||||
|
||||
1. **OBP çarpanı:** bir programa yerleştirildiysen (kayıt yaptırmasan bile) gelecek yıl diploma notu katkın yarıya düşer — hesabı [OBP yazısında](/rehber/obp-nedir-nasil-hesaplanir).
|
||||
2. **Tabanlar sabit durmaz:** bu yıl "az farkla kaçırdığın" bölümün tabanı seneye aynı yerde olmayabilir — [tabanlar nasıl değişir](/rehber/taban-siralamalar-nasil-degisir) yazısı bu oynaklığı verilerle gösteriyor.
|
||||
|
||||
## Bir dahaki listeye ders
|
||||
|
||||
Bu durumların neredeyse tamamı, liste kurulurken önlenebilir: sonuna gerçekten razı olacağın garantiler koymak, kayıt yaptırmayacağın satırı hiç yazmamak ve [ölü tercihleri](/rehber/olu-tercih-nedir) temizlemek. Ek yerleştirme listesi kuracaksan da aynı disiplin geçerli — sıralamana göre gerçekçi seçenekleri [tercih robotunda](/tercih-robotu) saniyeler içinde görebilirsin.
|
||||
37
content/rehber/yks-tercih-takvimi-2026.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
baslik: YKS 2026 Tercih Takvimi ve Süreç Adımları
|
||||
aciklama: Sonuçların açıklanmasından ek yerleştirmeye — 2026 tercih döneminin tüm aşamaları, sıralı ve tek sayfada.
|
||||
tarih: 2026-07-20
|
||||
---
|
||||
|
||||
Tercih dönemi kısa ve her adımı tarihli bir süreçtir. 2026'nın akışı şöyle işliyor (kesin tarihler için tek resmî kaynak ÖSYM duyurularıdır; buradaki çerçeve genel akışı gösterir):
|
||||
|
||||
## Sürecin aşamaları
|
||||
|
||||
**1) YKS sonuçlarının açıklanması (Temmuz ortası-sonu).**
|
||||
ÖSYM sonuç belgende puanların ve her puan türü için **başarı sıralaman** yazar. Tercihte kullanacağın sayı budur — puan değil ([neden olduğunu burada anlattık](/rehber/taban-puan-mi-siralama-mi)).
|
||||
|
||||
**2) Tercih kılavuzunun ve kontenjanların yayımlanması.**
|
||||
ÖSYM Yükseköğretim Programları ve Kontenjanları Kılavuzu'nu yayımlar; YÖK Atlas verileri güncellenir. Hangi programın kaç kişi alacağı ve geçen yılların tabanları netleşir.
|
||||
|
||||
**3) Tercih dönemi (Temmuz sonu — Ağustos başı, ~2 hafta).**
|
||||
2026'da tercihler 29 Temmuz - 10 Ağustos arasında alındı. Tercihler ÖSYM AİS (Aday İşlemleri Sistemi) üzerinden girilir; en fazla **24 tercih** hakkın vardır. Liste kurma yöntemi için [tercih listesi rehberine](/rehber/tercih-listesi-nasil-yapilir) bak; sıralamana uygun programları görmek için [tercih robotunu](/tercih-robotu) kullan.
|
||||
|
||||
**4) Yerleştirme sonuçlarının açıklanması (Ağustos).**
|
||||
Tercih döneminin kapanmasından yaklaşık 2-3 hafta sonra. Sonuçla birlikte her programın o yılki gerçek taban puanı ve sıralaması da netleşir.
|
||||
|
||||
**5) Kayıt dönemi (Ağustos sonu — Eylül başı).**
|
||||
Yerleştiğin programa e-Devlet üzerinden veya üniversiteye giderek kayıt yaptırırsın. Kayıt süresini kaçırmak hakkın yanması demektir — tarihleri takvimine işaretle.
|
||||
|
||||
**6) Ek yerleştirme (Eylül).**
|
||||
Boş kalan kontenjanlar için ikinci tur. Kritik kural: ilk yerleştirmede bir programa yerleşen, **kayıt yaptırmasa bile** ek tercihe başvuramaz. Detaylar [ek yerleştirme rehberinde](/rehber/ek-yerlestirme-2026).
|
||||
|
||||
## Tercih haftası için pratik plan
|
||||
|
||||
- **1. gün:** Sıralamanı doğrula, puan türünü netleştir.
|
||||
- **2-3. gün:** Program evrenini çıkar. [Bölüm taban puanları](/bolumler) tablolarında ilgilendiğin bölümlerin son yıllardaki tabanlarını incele; [Psikoloji](/bolum/psikoloji) gibi geniş bölümlerde aralığın ne kadar açıldığını görmek ufuk açar.
|
||||
- **4-5. gün:** Taslak listeyi kur: üstte hayal, ortada dengeli, altta gerçekten gideceğin garanti.
|
||||
- **6. gün:** Ölü tercih taraması yap ([nasıl yapılır](/rehber/olu-tercih-nedir)), aile onayını al, üniversitelerin özel şartlarını (kılavuz dipnotlarını) oku.
|
||||
- **Son gün değil, son günden önce:** AİS'e gir, listeyi kod kod işle, onayla, çıktısını sakla. Sistem son saatlerde yoğunluktan yavaşlar — son güne bırakma.
|
||||
|
||||
Tercih dönemi stresli görünür ama takvimi bilen için sadece sıralı bir yapılacaklar listesidir. Adımları sırayla yürü, kararlarını veriyle ver.
|
||||
BIN
data/app.db
BIN
data/yokatlas.db
27
docker-compose.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
container_name: kolaytercih
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- app-data:/app/data
|
||||
env_file:
|
||||
- .env.production
|
||||
environment:
|
||||
- APP_DB_URL=file:/app/data/app.db
|
||||
networks:
|
||||
- traefik
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.docker.network=traefik
|
||||
- traefik.http.routers.kolaytercih.rule=Host(`kolaytercih.com`)
|
||||
- traefik.http.routers.kolaytercih.entrypoints=websecure
|
||||
- traefik.http.routers.kolaytercih.tls.certresolver=letsencrypt
|
||||
- traefik.http.services.kolaytercih.loadbalancer.server.port=3000
|
||||
|
||||
networks:
|
||||
traefik:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
app-data:
|
||||
@@ -1,12 +1,18 @@
|
||||
import type { NextConfig } from "next";
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
// PPR: statik kabuk anında servis edilir, dinamik parçalar (UserNav vb.)
|
||||
// Suspense sınırlarının içinde akar. Bkz. docs/cacheComponents.md.
|
||||
cacheComponents: true,
|
||||
output: "standalone",
|
||||
serverExternalPackages: ["better-sqlite3", "iyzipay", "@libsql/client"],
|
||||
async redirects() {
|
||||
// Eski akış /sonuc modalına taşındı. /rapor/yazdir korunur (tam eşleşme).
|
||||
return [
|
||||
{ source: "/sohbet", destination: "/sonuc", permanent: false },
|
||||
{ source: "/rapor", destination: "/sonuc", permanent: false },
|
||||
{ source: "/sohbet", destination: "/listem", permanent: false },
|
||||
// Ayrı robot sayfası kaldırıldı; rehber içi linkler hero formuna düşer.
|
||||
{ source: "/tercih-robotu", destination: "/#hero-form", permanent: true },
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
18
package.json
@@ -8,11 +8,15 @@
|
||||
"start": "next start",
|
||||
"lint": "eslint",
|
||||
"ingest": "tsx scripts/ingest.ts",
|
||||
"refresh": "tsx scripts/refresh.ts"
|
||||
"refresh": "tsx scripts/refresh.ts",
|
||||
"detay": "tsx scripts/detay.ts",
|
||||
"logolar": "tsx scripts/logo-indir.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.112.4",
|
||||
"@cds/city": "^1.1.0",
|
||||
"@libsql/client": "^0.17.4",
|
||||
"@number-flow/react": "^0.6.2",
|
||||
"@react-pdf/renderer": "^4.5.1",
|
||||
"better-auth": "^1.6.23",
|
||||
"better-sqlite3": "^12.11.1",
|
||||
@@ -20,17 +24,29 @@
|
||||
"clsx": "^2.1.1",
|
||||
"drizzle-orm": "^0.45.2",
|
||||
"iyzipay": "^2.0.69",
|
||||
"lenis": "^1.3.25",
|
||||
"lucide-react": "^1.25.0",
|
||||
"marked": "^18.0.7",
|
||||
"mermaid": "^11.16.0",
|
||||
"motion": "^12.42.2",
|
||||
"next": "16.2.10",
|
||||
"next-themes": "^0.4.6",
|
||||
"radix-ui": "^1.6.3",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-use-measure": "^2.1.7",
|
||||
"remark-breaks": "^4.0.0",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"resend": "^6.18.0",
|
||||
"shiki": "^4.3.1",
|
||||
"simple-icons": "^16.27.1",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^3.6.0",
|
||||
"turkey-map-react": "^2.0.5",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"use-stick-to-bottom": "^1.1.6",
|
||||
"vaul": "^1.1.2",
|
||||
"zod": "^4.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
2029
pnpm-lock.yaml
generated
@@ -1 +0,0 @@
|
||||
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
||||
|
Before Width: | Height: | Size: 391 B |
@@ -1 +0,0 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
6
public/kolay-tercih-mark.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 180" role="img" aria-labelledby="title">
|
||||
<title id="title">KolayTercih</title>
|
||||
<rect x="27" y="56" width="57" height="57" rx="13" fill="#3b82f6"/>
|
||||
<rect x="91" y="29" width="56" height="56" rx="13" fill="#fdc7a7"/>
|
||||
<rect x="91" y="95" width="56" height="56" rx="13" fill="#ff5a00"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 355 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
BIN
public/uni-logo/abdullah-gul-universitesi.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
public/uni-logo/acibadem-mehmet-ali-aydinlar-universitesi.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
public/uni-logo/ada-kent-universitesi.png
Normal file
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 17 KiB |
BIN
public/uni-logo/adiyaman-universitesi.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
public/uni-logo/afyon-kocatepe-universitesi.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
public/uni-logo/afyonkarahisar-saglik-bilimleri-universitesi.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
public/uni-logo/agri-ibrahim-cecen-universitesi.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
public/uni-logo/akdeniz-karpaz-universitesi.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
public/uni-logo/akdeniz-universitesi.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/uni-logo/aksaray-universitesi.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
public/uni-logo/alanya-alaaddin-keykubat-universitesi.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
public/uni-logo/alanya-universitesi.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
BIN
public/uni-logo/altinbas-universitesi.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
public/uni-logo/amasya-universitesi.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
public/uni-logo/anadolu-universitesi.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
public/uni-logo/ankara-bilim-universitesi.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
public/uni-logo/ankara-haci-bayram-veli-universitesi.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
public/uni-logo/ankara-medipol-universitesi.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/uni-logo/ankara-muzik-ve-guzel-sanatlar-universitesi.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
public/uni-logo/ankara-sosyal-bilimler-universitesi.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/uni-logo/ankara-universitesi.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/uni-logo/ankara-yildirim-beyazit-universitesi.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
public/uni-logo/antalya-belek-universitesi.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
public/uni-logo/antalya-bilim-universitesi.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
public/uni-logo/ardahan-universitesi.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
BIN
public/uni-logo/artvin-coruh-universitesi.png
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
public/uni-logo/atasehir-adiguzel-meslek-yuksekokulu.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
public/uni-logo/ataturk-universitesi.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
public/uni-logo/atilim-universitesi.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
public/uni-logo/avrasya-universitesi.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
public/uni-logo/aydin-adnan-menderes-universitesi.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
public/uni-logo/azerbaycan-devlet-pedagoji-universitesi.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
public/uni-logo/bahcesehir-kibris-universitesi.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
public/uni-logo/bahcesehir-universitesi.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
public/uni-logo/balikesir-universitesi.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/uni-logo/bandirma-onyedi-eylul-universitesi.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
public/uni-logo/bartin-universitesi.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/uni-logo/baskent-universitesi.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
public/uni-logo/batman-universitesi.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/uni-logo/bayburt-universitesi.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
public/uni-logo/beykoz-universitesi.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
public/uni-logo/bezm-i-alem-vakif-universitesi.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
public/uni-logo/bilecik-seyh-edebali-universitesi.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
public/uni-logo/bingol-universitesi.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
public/uni-logo/biruni-universitesi.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
public/uni-logo/bitlis-eren-universitesi.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
public/uni-logo/bogazici-universitesi.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/uni-logo/bolu-abant-izzet-baysal-universitesi.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
public/uni-logo/burdur-mehmet-akif-ersoy-universitesi.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
public/uni-logo/bursa-teknik-universitesi.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
public/uni-logo/bursa-uludag-universitesi.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
public/uni-logo/cag-universitesi.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
public/uni-logo/canakkale-onsekiz-mart-universitesi.png
Normal file
|
After Width: | Height: | Size: 39 KiB |