Skip to content

Commit 12766ed

Browse files
committed
Add "Get Started" page and update sidebar navigation
Introduced a new "Get Started" page and added it to the main navigation in the sidebar. Updated sidebar styling for improved usability and adjusted mobile behavior to prevent auto-closing. Enhanced the overall layout and responsiveness of the sidebar components.
1 parent c632ee8 commit 12766ed

7 files changed

Lines changed: 630 additions & 113 deletions

File tree

src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import UniqueComponents from "./pages/showcase/UniqueComponents";
2929
import EcommerceShowcase from "./pages/showcase/EcommerceShowcase";
3030
import CryptoFinance from "./pages/showcase/CryptoFinance";
3131
import SocialMedia from "./pages/showcase/SocialMedia";
32+
import GetStarted from "./pages/GetStarted";
3233
import Login from "./pages/Login";
3334
import Register from "./pages/Register";
3435
import NotFound from "./pages/NotFound";
@@ -57,6 +58,7 @@ const App = () => (
5758
{/* Protected Routes - Inside AppLayout */}
5859
<Route element={<AppLayout />}>
5960
<Route path="/" element={<Dashboard />} />
61+
<Route path="/get-started" element={<GetStarted />} />
6062
<Route path="/tables" element={<TablesPage />} />
6163
<Route path="/forms" element={<FormsWizard />} />
6264
<Route path="/users" element={<UsersPage />} />

src/components/AppSidebar.tsx

Lines changed: 122 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import {
2020
Loader2,
2121
Image,
2222
ShoppingCart,
23-
DollarSign
23+
DollarSign,
24+
Activity,
25+
Rocket
2426
} from "lucide-react";
2527
import {
2628
Sidebar,
@@ -42,16 +44,12 @@ import { useLanguage } from "@/contexts/LanguageContext";
4244
export default function AppSidebar() {
4345
const location = useLocation();
4446
const { t } = useLanguage();
45-
const { state } = useSidebar();
47+
const { state, setOpenMobile } = useSidebar();
4648
const collapsed = state === "collapsed";
4749

4850
const mainItems = [
4951
{ title: t('nav.dashboard'), url: "/", icon: LayoutDashboard, badge: null },
50-
{ title: t('nav.analytics'), url: "/analytics", icon: BarChart3, badge: "Pro" },
51-
{ title: t('nav.tables'), url: "/tables", icon: Table2, badge: null },
52-
{ title: t('nav.forms'), url: "/forms", icon: FileInput, badge: "Beta" },
53-
{ title: t('nav.users'), url: "/users", icon: Users, badge: null },
54-
{ title: t('nav.roles'), url: "/roles", icon: Shield, badge: null },
52+
{ title: "Get Started", url: "/get-started", icon: Rocket, badge: "Guide" },
5553
];
5654

5755
const showcaseItems = [
@@ -70,6 +68,12 @@ export default function AppSidebar() {
7068
{ title: "E-commerce Showcase", url: "/showcase/ecommerce", icon: ShoppingCart, badge: "Premium", isChild: true },
7169
{ title: "Crypto & Finance", url: "/showcase/crypto-finance", icon: DollarSign, badge: "Premium", isChild: true },
7270
{ title: "Social Media", url: "/showcase/social-media", icon: Users, badge: "Premium", isChild: true },
71+
// Ana menüden taşınan öğeler
72+
{ title: t('nav.analytics'), url: "/analytics", icon: BarChart3, badge: "Pro", isChild: true },
73+
{ title: t('nav.tables'), url: "/tables", icon: Table2, badge: null, isChild: true },
74+
{ title: t('nav.forms'), url: "/forms", icon: FileInput, badge: "Beta", isChild: true },
75+
{ title: t('nav.users'), url: "/users", icon: Users, badge: null, isChild: true },
76+
{ title: t('nav.roles'), url: "/roles", icon: Shield, badge: null, isChild: true },
7377
];
7478

7579
const settingsItems = [
@@ -93,10 +97,10 @@ export default function AppSidebar() {
9397
const getNavClassName = (path: string) => {
9498
const active = isActive(path);
9599
return `
96-
relative group flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-all duration-200
100+
relative group flex items-center gap-4 rounded-xl px-4 py-3 text-sm font-medium transition-all duration-300 min-h-[44px]
97101
${active
98-
? "bg-gradient-to-r from-primary/20 to-primary/10 text-primary border-r-2 border-primary shadow-sm"
99-
: "text-muted-foreground hover:text-foreground hover:bg-muted/50"
102+
? "bg-gradient-to-r from-primary/15 via-primary/10 to-primary/5 text-primary border-l-4 border-primary shadow-lg shadow-primary/20"
103+
: "text-muted-foreground hover:text-foreground hover:bg-muted/50 hover:shadow-md"
100104
}
101105
${collapsed ? "justify-center" : ""}
102106
`;
@@ -121,33 +125,42 @@ export default function AppSidebar() {
121125
</div>
122126
</SidebarHeader>
123127

124-
<SidebarContent className="p-4 space-y-6">
128+
<SidebarContent className="p-6 space-y-8 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-sidebar-border/50 hover:scrollbar-thumb-sidebar-border/70">
125129
{/* Main Navigation */}
126130
<SidebarGroup>
127131
<SidebarGroupLabel className="flex items-center gap-2 px-0 text-xs font-semibold uppercase tracking-wider text-muted-foreground/80">
128132
<LayoutDashboard className="h-3 w-3" />
129133
{!collapsed && "Ana Menü"}
130134
</SidebarGroupLabel>
131135
<SidebarGroupContent>
132-
<SidebarMenu className="space-y-1">
133-
{mainItems.map((item) => (
136+
<SidebarMenu className="space-y-2">
137+
{mainItems.map((item) => (
134138
<SidebarMenuItem key={item.title}>
135139
<SidebarMenuButton asChild className="p-0">
136-
<NavLink to={item.url} className={getNavClassName(item.url)}>
137-
<item.icon className="h-4 w-4 flex-shrink-0" />
138-
{!collapsed && (
139-
<>
140-
<span className="flex-1">{item.title}</span>
141-
{item.badge && (
142-
<Badge variant={item.badge === "Pro" ? "default" : "secondary"} className="text-xs">
143-
{item.badge}
144-
</Badge>
145-
)}
146-
{isActive(item.url) && (
147-
<ChevronRight className="h-3 w-3 text-primary" />
148-
)}
149-
</>
150-
)}
140+
<NavLink
141+
to={item.url}
142+
className={getNavClassName(item.url)}
143+
onClick={() => {
144+
// Prevent sidebar from auto-closing on mobile
145+
if (window.innerWidth < 1024) {
146+
setOpenMobile(false);
147+
}
148+
}}
149+
>
150+
<item.icon className="h-5 w-5 flex-shrink-0" />
151+
{!collapsed && (
152+
<>
153+
<span className="flex-1 font-medium leading-tight">{item.title}</span>
154+
{item.badge && (
155+
<Badge variant={item.badge === "Pro" ? "default" : "secondary"} className="text-xs px-2 py-1 flex-shrink-0">
156+
{item.badge}
157+
</Badge>
158+
)}
159+
{isActive(item.url) && (
160+
<ChevronRight className="h-4 w-4 text-primary animate-pulse flex-shrink-0" />
161+
)}
162+
</>
163+
)}
151164
</NavLink>
152165
</SidebarMenuButton>
153166
</SidebarMenuItem>
@@ -163,34 +176,43 @@ export default function AppSidebar() {
163176
{!collapsed && "Showcase"}
164177
</SidebarGroupLabel>
165178
<SidebarGroupContent>
166-
<SidebarMenu className="space-y-1">
167-
{showcaseItems.map((item) => (
179+
<SidebarMenu className="space-y-2">
180+
{showcaseItems.map((item) => (
168181
<SidebarMenuItem key={item.title}>
169182
<SidebarMenuButton asChild className="p-0">
170-
<NavLink to={item.url} className={`${getNavClassName(item.url)} ${item.isChild ? 'ml-4 text-sm' : ''}`}>
171-
{item.isChild ? (
172-
<div className="h-4 w-4 flex items-center justify-center flex-shrink-0">
173-
<item.icon className="h-3 w-3 text-muted-foreground" />
174-
</div>
175-
) : (
176-
<div className="flex h-4 w-4 items-center justify-center rounded bg-gradient-to-br from-yellow-400 to-orange-500 flex-shrink-0">
177-
<item.icon className="h-3 w-3 text-white" />
178-
</div>
179-
)}
180-
{!collapsed && (
181-
<>
182-
<span className="flex-1">{item.title}</span>
183-
{item.badge && (
184-
<Badge variant={item.isChild ? "secondary" : "outline"} className={`text-xs ${item.isChild ? '' : 'border-yellow-500 text-yellow-600'}`}>
185-
{item.isChild ? item.badge : `${item.badge} Kategori`}
186-
</Badge>
187-
)}
188-
{isActive(item.url) && (
189-
<ChevronRight className="h-3 w-3 text-primary" />
190-
)}
191-
</>
192-
)}
193-
</NavLink>
183+
<NavLink
184+
to={item.url}
185+
className={`${getNavClassName(item.url)} ${item.isChild ? 'ml-6 text-sm' : ''}`}
186+
onClick={() => {
187+
// Prevent sidebar from auto-closing on mobile
188+
if (window.innerWidth < 1024) {
189+
setOpenMobile(false);
190+
}
191+
}}
192+
>
193+
{item.isChild ? (
194+
<div className="h-5 w-5 flex items-center justify-center flex-shrink-0">
195+
<item.icon className="h-4 w-4 text-muted-foreground" />
196+
</div>
197+
) : (
198+
<div className="flex h-5 w-5 items-center justify-center rounded-lg bg-gradient-to-br from-yellow-400 to-orange-500 flex-shrink-0 shadow-sm">
199+
<item.icon className="h-4 w-4 text-white" />
200+
</div>
201+
)}
202+
{!collapsed && (
203+
<>
204+
<span className="flex-1 font-medium leading-tight">{item.title}</span>
205+
{item.badge && (
206+
<Badge variant={item.isChild ? "secondary" : "outline"} className={`text-xs px-2 py-1 flex-shrink-0 ${item.isChild ? 'bg-muted/80' : 'border-yellow-500 text-yellow-600'}`}>
207+
{item.isChild ? item.badge : `${item.badge} Kategori`}
208+
</Badge>
209+
)}
210+
{isActive(item.url) && (
211+
<ChevronRight className="h-4 w-4 text-primary animate-pulse flex-shrink-0" />
212+
)}
213+
</>
214+
)}
215+
</NavLink>
194216
</SidebarMenuButton>
195217
</SidebarMenuItem>
196218
))}
@@ -205,25 +227,34 @@ export default function AppSidebar() {
205227
{!collapsed && "Ayarlar"}
206228
</SidebarGroupLabel>
207229
<SidebarGroupContent>
208-
<SidebarMenu className="space-y-1">
209-
{settingsItems.map((item) => (
230+
<SidebarMenu className="space-y-2">
231+
{settingsItems.map((item) => (
210232
<SidebarMenuItem key={item.title}>
211233
<SidebarMenuButton asChild className="p-0">
212-
<NavLink to={item.url} className={getNavClassName(item.url)}>
213-
<item.icon className="h-4 w-4 flex-shrink-0" />
214-
{!collapsed && (
215-
<>
216-
<span className="flex-1">{item.title}</span>
217-
{item.badge && (
218-
<Badge variant="destructive" className="text-xs">
219-
{item.badge}
220-
</Badge>
221-
)}
222-
{isActive(item.url) && (
223-
<ChevronRight className="h-3 w-3 text-primary" />
224-
)}
225-
</>
226-
)}
234+
<NavLink
235+
to={item.url}
236+
className={getNavClassName(item.url)}
237+
onClick={() => {
238+
// Prevent sidebar from auto-closing on mobile
239+
if (window.innerWidth < 1024) {
240+
setOpenMobile(false);
241+
}
242+
}}
243+
>
244+
<item.icon className="h-5 w-5 flex-shrink-0" />
245+
{!collapsed && (
246+
<>
247+
<span className="flex-1 font-medium leading-tight">{item.title}</span>
248+
{item.badge && (
249+
<Badge variant="destructive" className="text-xs px-2 py-1 flex-shrink-0">
250+
{item.badge}
251+
</Badge>
252+
)}
253+
{isActive(item.url) && (
254+
<ChevronRight className="h-4 w-4 text-primary animate-pulse flex-shrink-0" />
255+
)}
256+
</>
257+
)}
227258
</NavLink>
228259
</SidebarMenuButton>
229260
</SidebarMenuItem>
@@ -240,20 +271,29 @@ export default function AppSidebar() {
240271
{!collapsed && "Giriş"}
241272
</SidebarGroupLabel>
242273
<SidebarGroupContent>
243-
<SidebarMenu className="space-y-1">
274+
<SidebarMenu className="space-y-2">
244275
{authItems.map((item) => (
245276
<SidebarMenuItem key={item.title}>
246277
<SidebarMenuButton asChild className="p-0">
247-
<NavLink to={item.url} className={getNavClassName(item.url)}>
248-
<item.icon className="h-4 w-4 flex-shrink-0" />
249-
{!collapsed && (
250-
<>
251-
<span className="flex-1">{item.title}</span>
252-
{isActive(item.url) && (
253-
<ChevronRight className="h-3 w-3 text-primary" />
254-
)}
255-
</>
256-
)}
278+
<NavLink
279+
to={item.url}
280+
className={getNavClassName(item.url)}
281+
onClick={() => {
282+
// Prevent sidebar from auto-closing on mobile
283+
if (window.innerWidth < 1024) {
284+
setOpenMobile(false);
285+
}
286+
}}
287+
>
288+
<item.icon className="h-5 w-5 flex-shrink-0" />
289+
{!collapsed && (
290+
<>
291+
<span className="flex-1 font-medium leading-tight">{item.title}</span>
292+
{isActive(item.url) && (
293+
<ChevronRight className="h-4 w-4 text-primary animate-pulse flex-shrink-0" />
294+
)}
295+
</>
296+
)}
257297
</NavLink>
258298
</SidebarMenuButton>
259299
</SidebarMenuItem>

src/components/ui/sidebar.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919

2020
const SIDEBAR_COOKIE_NAME = "sidebar:state"
2121
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
22-
const SIDEBAR_WIDTH = "16rem"
22+
const SIDEBAR_WIDTH = "20rem"
2323
const SIDEBAR_WIDTH_MOBILE = "18rem"
2424
const SIDEBAR_WIDTH_ICON = "3rem"
2525
const SIDEBAR_KEYBOARD_SHORTCUT = "b"
@@ -192,7 +192,7 @@ const Sidebar = React.forwardRef<
192192

193193
if (isMobile) {
194194
return (
195-
<Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
195+
<Sheet open={openMobile} onOpenChange={setOpenMobile} modal={false} {...props}>
196196
<SheetContent
197197
data-sidebar="sidebar"
198198
data-mobile="true"
@@ -203,6 +203,10 @@ const Sidebar = React.forwardRef<
203203
} as React.CSSProperties
204204
}
205205
side={side}
206+
onInteractOutside={(e) => {
207+
// Prevent auto-closing when clicking outside
208+
e.preventDefault();
209+
}}
206210
>
207211
<div className="flex h-full w-full flex-col">{children}</div>
208212
</SheetContent>

src/contexts/ThemeContext.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
1313
export function ThemeProvider({ children }: { children: React.ReactNode }) {
1414
const [theme, setTheme] = useState<Theme>(() => {
1515
const saved = localStorage.getItem('theme');
16-
return (saved as Theme) || 'system';
16+
return (saved as Theme) || 'light';
1717
});
1818

1919
const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>('light');

src/hooks/use-mobile.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from "react"
22

3-
const MOBILE_BREAKPOINT = 768
3+
const MOBILE_BREAKPOINT = 1024
44

55
export function useIsMobile() {
66
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)

0 commit comments

Comments
 (0)