Feat: Mobile responsiveness improvements (sidebar, calendar)
This commit is contained in:
@@ -1,15 +1,22 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
import { MainNav } from "@/components/main-nav"
|
import { MainNav } from "@/components/main-nav"
|
||||||
import { UserNav } from "@/components/user-nav"
|
import { UserNav } from "@/components/user-nav"
|
||||||
import { Building } from "lucide-react"
|
import { Building, Menu } from "lucide-react"
|
||||||
|
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"
|
||||||
|
import { Button } from "@/components/ui/button"
|
||||||
|
import { useState } from "react"
|
||||||
|
|
||||||
export default function DashboardLayout({
|
export default function DashboardLayout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
}) {
|
}) {
|
||||||
|
const [isMobileOpen, setIsMobileOpen] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen bg-gray-50/50 dark:bg-gray-900/50">
|
<div className="flex min-h-screen bg-gray-50/50 dark:bg-gray-900/50">
|
||||||
{/* Sidebar */}
|
{/* Desktop Sidebar */}
|
||||||
<aside className="hidden md:flex w-72 flex-col fixed inset-y-0 z-50 bg-white dark:bg-gray-950 border-r shadow-sm">
|
<aside className="hidden md:flex w-72 flex-col fixed inset-y-0 z-50 bg-white dark:bg-gray-950 border-r shadow-sm">
|
||||||
<MainNav />
|
<MainNav />
|
||||||
</aside>
|
</aside>
|
||||||
@@ -17,11 +24,24 @@ export default function DashboardLayout({
|
|||||||
{/* Main Content */}
|
{/* Main Content */}
|
||||||
<div className="flex-1 md:ml-72 flex flex-col min-h-screen">
|
<div className="flex-1 md:ml-72 flex flex-col min-h-screen">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<header className="sticky top-0 z-40 h-16 glass border-b px-6 flex items-center justify-between">
|
<header className="sticky top-0 z-40 h-16 glass border-b px-4 md:px-6 flex items-center justify-between">
|
||||||
<div className="md:hidden flex items-center font-bold text-xl">
|
<div className="flex items-center gap-2 md:hidden">
|
||||||
<Building className="mr-2 h-6 w-6 text-primary" />
|
<Sheet open={isMobileOpen} onOpenChange={setIsMobileOpen}>
|
||||||
|
<SheetTrigger asChild>
|
||||||
|
<Button variant="ghost" size="icon" className="md:hidden">
|
||||||
|
<Menu className="h-6 w-6" />
|
||||||
|
<span className="sr-only">Menüyü aç</span>
|
||||||
|
</Button>
|
||||||
|
</SheetTrigger>
|
||||||
|
<SheetContent side="left" className="p-0 w-72">
|
||||||
|
<MainNav onNavClick={() => setIsMobileOpen(false)} />
|
||||||
|
</SheetContent>
|
||||||
|
</Sheet>
|
||||||
|
<div className="flex items-center font-bold text-lg">
|
||||||
|
<Building className="mr-2 h-5 w-5 text-primary" />
|
||||||
WeddingOS
|
WeddingOS
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="ml-auto flex items-center space-x-4">
|
<div className="ml-auto flex items-center space-x-4">
|
||||||
<UserNav />
|
<UserNav />
|
||||||
@@ -29,7 +49,7 @@ export default function DashboardLayout({
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
{/* Page Content */}
|
{/* Page Content */}
|
||||||
<main className="flex-1 p-6 md:p-8 overflow-y-auto">
|
<main className="flex-1 p-4 md:p-8 overflow-y-auto overflow-x-hidden">
|
||||||
<div className="max-w-7xl mx-auto animate-in fade-in slide-in-from-bottom-4 duration-500">
|
<div className="max-w-7xl mx-auto animate-in fade-in slide-in-from-bottom-4 duration-500">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import startOfWeek from 'date-fns/startOfWeek'
|
|||||||
import getDay from 'date-fns/getDay'
|
import getDay from 'date-fns/getDay'
|
||||||
import tr from 'date-fns/locale/tr'
|
import tr from 'date-fns/locale/tr'
|
||||||
import "react-big-calendar/lib/css/react-big-calendar.css"
|
import "react-big-calendar/lib/css/react-big-calendar.css"
|
||||||
import { useState, useMemo } from 'react'
|
import { useState, useMemo, useEffect } from 'react'
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
||||||
import { useRouter } from 'next/navigation'
|
import { useRouter } from 'next/navigation'
|
||||||
@@ -40,6 +40,14 @@ export function CalendarView({ events = [], halls = [] }: CalendarViewProps) {
|
|||||||
const [view, setView] = useState<View>(Views.MONTH)
|
const [view, setView] = useState<View>(Views.MONTH)
|
||||||
const [date, setDate] = useState(new Date())
|
const [date, setDate] = useState(new Date())
|
||||||
const [selectedHallId, setSelectedHallId] = useState<string>("all")
|
const [selectedHallId, setSelectedHallId] = useState<string>("all")
|
||||||
|
const [isMobile, setIsMobile] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const checkMobile = () => setIsMobile(window.innerWidth < 768)
|
||||||
|
checkMobile()
|
||||||
|
window.addEventListener('resize', checkMobile)
|
||||||
|
return () => window.removeEventListener('resize', checkMobile)
|
||||||
|
}, [])
|
||||||
|
|
||||||
const filteredEvents = useMemo(() => {
|
const filteredEvents = useMemo(() => {
|
||||||
if (selectedHallId === "all") return events
|
if (selectedHallId === "all") return events
|
||||||
@@ -51,19 +59,14 @@ export function CalendarView({ events = [], halls = [] }: CalendarViewProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleSelectSlot = ({ start, end }: { start: Date, end: Date }) => {
|
const handleSelectSlot = ({ start, end }: { start: Date, end: Date }) => {
|
||||||
// Optional: Navigate to create page with pre-filled dates
|
// Optional: Navigate to create page
|
||||||
// const params = new URLSearchParams()
|
|
||||||
// params.set('date', format(start, 'yyyy-MM-dd'))
|
|
||||||
// params.set('start', format(start, 'HH:mm'))
|
|
||||||
// params.set('end', format(end, 'HH:mm'))
|
|
||||||
// router.push(`/dashboard/reservations/new?${params.toString()}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="h-[700px] flex flex-col">
|
<Card className="h-[calc(100vh-10rem)] min-h-[500px] flex flex-col">
|
||||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-4">
|
<CardHeader className="flex flex-col md:flex-row items-start md:items-center justify-between space-y-2 md:space-y-0 pb-4">
|
||||||
<CardTitle>Rezervasyon Takvimi</CardTitle>
|
<CardTitle>Rezervasyon Takvimi</CardTitle>
|
||||||
<div className="w-[200px]">
|
<div className="w-full md:w-[200px]">
|
||||||
<Select value={selectedHallId} onValueChange={setSelectedHallId}>
|
<Select value={selectedHallId} onValueChange={setSelectedHallId}>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Salon Seçin" />
|
<SelectValue placeholder="Salon Seçin" />
|
||||||
@@ -77,9 +80,11 @@ export function CalendarView({ events = [], halls = [] }: CalendarViewProps) {
|
|||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex-1 pb-4">
|
<CardContent className="flex-1 pb-4 overflow-hidden">
|
||||||
<ContextMenu>
|
<ContextMenu>
|
||||||
<ContextMenuTrigger className="h-full w-full">
|
<ContextMenuTrigger className="h-full w-full">
|
||||||
|
<div className="h-full w-full overflow-x-auto">
|
||||||
|
<div className="min-w-[300px] h-full">
|
||||||
<Calendar
|
<Calendar
|
||||||
localizer={localizer}
|
localizer={localizer}
|
||||||
events={filteredEvents}
|
events={filteredEvents}
|
||||||
@@ -111,6 +116,8 @@ export function CalendarView({ events = [], halls = [] }: CalendarViewProps) {
|
|||||||
className: "bg-primary text-primary-foreground text-xs rounded-md border-none px-2 py-1 shadow-sm hover:bg-primary/90 transition-colors cursor-pointer"
|
className: "bg-primary text-primary-foreground text-xs rounded-md border-none px-2 py-1 shadow-sm hover:bg-primary/90 transition-colors cursor-pointer"
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</ContextMenuTrigger>
|
</ContextMenuTrigger>
|
||||||
<ContextMenuContent>
|
<ContextMenuContent>
|
||||||
<ContextMenuItem onClick={() => router.push('/dashboard/reservations/new')}>
|
<ContextMenuItem onClick={() => router.push('/dashboard/reservations/new')}>
|
||||||
|
|||||||
@@ -6,10 +6,15 @@ import { cn } from "@/lib/utils"
|
|||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { CalendarDays, Users, Home, Settings, Building2, CreditCard, LogOut } from "lucide-react"
|
import { CalendarDays, Users, Home, Settings, Building2, CreditCard, LogOut } from "lucide-react"
|
||||||
|
|
||||||
|
interface MainNavProps extends React.HTMLAttributes<HTMLElement> {
|
||||||
|
onNavClick?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
export function MainNav({
|
export function MainNav({
|
||||||
className,
|
className,
|
||||||
|
onNavClick,
|
||||||
...props
|
...props
|
||||||
}: React.HTMLAttributes<HTMLElement>) {
|
}: MainNavProps) {
|
||||||
const pathname = usePathname()
|
const pathname = usePathname()
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
@@ -65,7 +70,7 @@ export function MainNav({
|
|||||||
|
|
||||||
<div className="flex-1 px-2 space-y-1">
|
<div className="flex-1 px-2 space-y-1">
|
||||||
{routes.map((route) => (
|
{routes.map((route) => (
|
||||||
<Link key={route.href} href={route.href}>
|
<Link key={route.href} href={route.href} onClick={onNavClick}>
|
||||||
<Button
|
<Button
|
||||||
variant={route.active ? "secondary" : "ghost"}
|
variant={route.active ? "secondary" : "ghost"}
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|||||||
Reference in New Issue
Block a user