Skip to content

Commit f656833

Browse files
authored
Merge pull request #134 from devxtra-community/feature/resp
make the brand dashboard responsive
2 parents 983f4e6 + bac22d0 commit f656833

14 files changed

Lines changed: 743 additions & 545 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ dist
55
.next
66
!.env.example
77
data.ms/
8+
data.ms/
9+
*.mdb

apps/core-api/src/middlewares/rateLimit.middleware.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { rateLimit } from 'express-rate-limit';
1+
import { Request, Response, NextFunction } from 'express';
2+
import { rateLimit, Options } from 'express-rate-limit';
23

34
export const authLimiter = rateLimit({
45
windowMs: 15 * 60 * 1000, // 15 minutes
@@ -9,7 +10,7 @@ export const authLimiter = rateLimit({
910
success: false,
1011
message: "Too many authentication attempts. Please try again later.",
1112
},
12-
handler: (req, res, next, options) => {
13+
handler: (req: Request, res: Response, next: NextFunction, options: Options) => {
1314
res.status(429).json(options.message);
1415
},
1516
});

apps/web/app/brand-dashboard/bookings/page.tsx

Lines changed: 146 additions & 113 deletions
Large diffs are not rendered by default.

apps/web/app/brand-dashboard/calendar/page.tsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,14 @@ export default function BrandCalendarPage() {
114114
}
115115

116116
return (
117-
<div className="px-4 sm:px-6 lg:px-8 py-8 h-full flex flex-col min-h-0 bg-[#f8fafc]">
118-
<div className="flex flex-col lg:flex-row gap-8 flex-1 overflow-hidden">
117+
<div className="px-4 sm:px-6 lg:px-8 py-4 sm:py-8 h-full flex flex-col min-h-0 bg-[#f8fafc]">
118+
<div className="flex flex-col lg:flex-row gap-6 lg:gap-8 flex-1 overflow-y-auto lg:overflow-hidden pb-20 lg:pb-0">
119119
{/* Left Column: Calendar Grid */}
120-
<div className="flex-1 bg-white rounded-[2.5rem] border border-gray-100 shadow-sm p-10 flex flex-col items-center">
120+
<div className="flex-1 bg-white rounded-[1.5rem] lg:rounded-[2.5rem] border border-gray-100 shadow-sm p-5 sm:p-8 lg:p-10 flex flex-col items-center lg:overflow-y-auto">
121121
<div className="w-full max-w-2xl">
122-
<div className="flex items-center justify-between mb-12">
123-
<h1 className="text-2xl font-bold text-gray-900 tracking-tight">Select Date</h1>
124-
<div className="flex items-center gap-6">
122+
<div className="flex flex-col sm:flex-row items-center justify-between gap-4 mb-8 sm:mb-12">
123+
<h1 className="text-xl sm:text-2xl font-bold text-gray-900 tracking-tight">Select Date</h1>
124+
<div className="flex items-center gap-4 sm:gap-6">
125125
<button
126126
onClick={() => handleMonthChange(-1)}
127127
className="p-2 hover:bg-gray-50 rounded-full transition-all text-gray-400"
@@ -146,16 +146,16 @@ export default function BrandCalendarPage() {
146146
))}
147147
</div>
148148

149-
<div className="grid grid-cols-7 gap-y-10 gap-x-4 mb-16 w-full">
149+
<div className="grid grid-cols-7 gap-y-6 sm:gap-y-10 gap-x-2 sm:gap-x-4 mb-10 sm:mb-16 w-full">
150150
{Array.from({ length: firstDayOfMonth(currentDate.getFullYear(), currentDate.getMonth()) }).map((_, i) => (
151-
<div key={`empty-${i}`} className="h-14"></div>
151+
<div key={`empty-${i}`} className="h-10 sm:h-14"></div>
152152
))}
153153

154154
{days.map((date) => (
155-
<div key={date.day} className="h-14 flex flex-col items-center justify-center relative">
155+
<div key={date.day} className="h-10 sm:h-14 flex flex-col items-center justify-center relative">
156156
<button
157157
onClick={() => setSelectedDate(date.day)}
158-
className={`w-14 h-14 rounded-full flex items-center justify-center text-[15px] font-bold transition-all relative z-10 ${selectedDate === date.day
158+
className={`w-10 h-10 sm:w-14 sm:h-14 rounded-full flex items-center justify-center text-[13px] sm:text-[15px] font-bold transition-all relative z-10 ${selectedDate === date.day
159159
? "bg-emerald-500 text-white shadow-xl shadow-emerald-200 scale-110"
160160
: "text-gray-900 hover:bg-gray-50"
161161
}`}
@@ -181,10 +181,10 @@ export default function BrandCalendarPage() {
181181
</div>
182182

183183
{/* Right Column: Day Schedule */}
184-
<div className="lg:w-[450px] flex flex-col">
185-
<div className="mb-6 pl-2">
186-
<span className="text-[11px] font-black text-emerald-500 uppercase tracking-[0.2em]">Expected Delivery</span>
187-
<h2 className="text-3xl font-black text-gray-900 mt-2">{monthNames[currentDate.getMonth()]} {selectedDate}, {currentDate.getFullYear()}</h2>
184+
<div className="lg:w-[450px] flex flex-col shrink-0 lg:overflow-y-hidden">
185+
<div className="mb-4 sm:mb-6 pl-2 text-center lg:text-left mt-4 lg:mt-0">
186+
<span className="text-[10px] sm:text-[11px] font-black text-emerald-500 uppercase tracking-[0.2em]">Expected Delivery</span>
187+
<h2 className="text-2xl sm:text-3xl font-black text-gray-900 mt-1 sm:mt-2">{monthNames[currentDate.getMonth()]} {selectedDate}, {currentDate.getFullYear()}</h2>
188188
</div>
189189

190190
<div className="space-y-4 overflow-y-auto pr-2 pb-8 flex-1">

apps/web/app/brand-dashboard/layout.tsx

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,83 +38,96 @@ export default function BrandDashboardLayout({
3838
{ name: "Overview", href: "/brand-dashboard", icon: LayoutDashboard },
3939
{ name: "Requests", href: "/brand-dashboard/requests", icon: Users, badge: counts.pendingRequestsCount > 0 ? counts.pendingRequestsCount.toString() : undefined },
4040
{ name: "Bookings", href: "/brand-dashboard/bookings", icon: Briefcase },
41-
{ name: "Messages", href: "/brand-dashboard/messages", icon: MessageSquare, badge: counts.unreadMessagesCount > 0 ? counts.unreadMessagesCount.toString() : undefined, badgeColor: "bg-rose-100 text-rose-600" },
41+
{ name: "Messages", href: "/brand-dashboard/messages", icon: MessageSquare, badge: counts.unreadMessagesCount > 0 ? counts.unreadMessagesCount.toString() : undefined, badgeColor: "bg-rose-500 text-white shadow-lg shadow-rose-200" },
4242
{ name: "Calendar", href: "/brand-dashboard/calendar", icon: Calendar },
4343
{ name: "Transactions", href: "/brand-dashboard/transactions", icon: ArrowLeftRight },
4444
];
4545

4646
return (
4747
<RoleGuard allowedRoles={["BRAND"]}>
48-
<div className="flex h-screen bg-[#F1F5F9] overflow-hidden">
48+
<div className="flex h-[100dvh] bg-[#F8FAFC] overflow-hidden font-sans">
4949

5050
{/* Mobile Sidebar Overlay */}
5151
{isSidebarOpen && (
5252
<div
53-
className="fixed inset-0 bg-black/20 z-40 lg:hidden"
53+
className="fixed inset-0 bg-slate-900/40 backdrop-blur-sm z-40 lg:hidden transition-all duration-300"
5454
onClick={() => setIsSidebarOpen(false)}
5555
/>
5656
)}
5757

5858
{/* Sidebar */}
59-
<aside className={`fixed lg:static inset-y-0 left-0 w-64 bg-white border-r border-gray-100 flex flex-col py-6 shrink-0 transition-transform duration-300 z-50 lg:translate-x-0 ${isSidebarOpen ? "translate-x-0" : "-translate-x-full"}`}>
60-
<div className="flex items-center justify-between px-6 mb-10">
61-
<div className="flex items-center gap-3">
62-
<div className="w-8 h-8 rounded-lg overflow-hidden shrink-0 flex items-center justify-center bg-gray-50 border border-gray-200">
63-
<Image src="/favicon.ico" alt="Noillin" width={20} height={20} className="object-contain" />
59+
<aside className={`fixed lg:static inset-y-0 left-0 w-72 bg-white border-r border-slate-100 flex flex-col py-6 shrink-0 transition-transform duration-300 ease-in-out z-50 shadow-2xl lg:shadow-none lg:translate-x-0 ${isSidebarOpen ? "translate-x-0" : "-translate-x-full"}`}>
60+
<div className="flex items-center justify-between px-8 mb-10">
61+
<div className="flex items-center gap-3 group cursor-pointer">
62+
<div className="w-9 h-9 rounded-xl overflow-hidden shrink-0 flex items-center justify-center bg-emerald-50 border border-emerald-100 group-hover:shadow-md group-hover:shadow-emerald-100 transition-all">
63+
<Image src="/favicon.ico" alt="Noillin" width={22} height={22} className="object-contain" />
6464
</div>
65-
<span className="font-bold text-gray-900 text-lg tracking-tight">Noillin</span>
65+
<span className="font-black text-slate-900 text-xl tracking-tight">Noillin</span>
6666
</div>
67-
<button className="lg:hidden text-gray-500" onClick={() => setIsSidebarOpen(false)}>
68-
<X className="w-6 h-6" />
67+
<button className="lg:hidden p-2 rounded-lg text-slate-400 hover:bg-slate-50 hover:text-slate-600 transition-colors" onClick={() => setIsSidebarOpen(false)}>
68+
<X className="w-5 h-5" />
6969
</button>
7070
</div>
7171

72-
<nav className="flex flex-col gap-1 flex-1 px-4">
72+
<div className="px-8 mb-4">
73+
<p className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Main Menu</p>
74+
</div>
75+
76+
<nav className="flex flex-col gap-1.5 flex-1 px-4">
7377
{navItems.map((item) => {
7478
const isActive = pathname === item.href;
7579
const Icon = item.icon;
7680
return (
7781
<Link
7882
key={item.name}
7983
href={item.href}
80-
className={`flex items-center justify-between px-3 py-2.5 rounded-xl transition-colors ${isActive ? "bg-emerald-50 text-emerald-600 font-medium" : "text-gray-500 hover:bg-gray-50 hover:text-gray-900"}`}
84+
onClick={() => setIsSidebarOpen(false)}
85+
className={`relative flex items-center justify-between px-4 py-3.5 rounded-2xl transition-all duration-200 group overflow-hidden ${isActive ? "bg-emerald-500 text-white shadow-xl shadow-emerald-500/20" : "text-slate-500 hover:bg-slate-50 hover:text-slate-900"}`}
8186
>
82-
<div className="flex items-center gap-3">
83-
<Icon className="w-5 h-5" />
84-
<span className="text-sm">{item.name}</span>
87+
{isActive && (
88+
<div className="absolute inset-0 bg-gradient-to-r from-emerald-400/0 via-white/10 to-emerald-400/0 translate-x-[-100%] group-hover:translate-x-[100%] transition-transform duration-1000" />
89+
)}
90+
<div className="flex items-center gap-3.5 relative z-10">
91+
<Icon className={`w-5 h-5 ${isActive ? "text-white" : "text-slate-400 group-hover:text-emerald-500"} transition-colors`} />
92+
<span className={`text-[14px] ${isActive ? "font-bold" : "font-semibold"}`}>{item.name}</span>
8593
</div>
8694
{item.badge && (
87-
<span className={`${item.badgeColor || "bg-emerald-100 text-emerald-600"} text-xs font-bold px-2 py-0.5 rounded-full`}>
95+
<span className={`relative z-10 ${item.badgeColor || (isActive ? "bg-white/20 text-white" : "bg-emerald-100 text-emerald-600")} text-[10px] font-black px-2.5 py-0.5 rounded-full`}>
8896
{item.badge}
8997
</span>
9098
)}
9199
</Link>
92100
);
93101
})}
94102
</nav>
103+
95104
</aside>
96105

97106
{/* Main Header & Content Area */}
98-
<main className="flex-1 flex flex-col min-w-0 h-screen overflow-hidden">
107+
<main className="flex-1 flex flex-col min-w-0 h-[100dvh] overflow-hidden bg-slate-50/50">
99108
{/* Dashboard Header */}
100109
<DashboardHeader
101110
isFixed={false}
102111
showSidebarToggle={true}
103112
hideLogo={true}
104113
onSidebarToggle={() => setIsSidebarOpen(true)}
105114
>
106-
<div className="flex items-center gap-6">
115+
<div className="flex items-center gap-4 sm:gap-6">
107116
<Link
108117
href="/gig-list"
109-
className="hidden md:flex items-center justify-center bg-emerald-500 hover:bg-emerald-600 text-white px-5 py-2 rounded-xl font-bold text-sm transition-colors shadow-sm"
118+
className="hidden md:flex items-center justify-center bg-emerald-500 hover:bg-emerald-600 text-white px-5 py-2 rounded-xl font-bold text-xs transition-all shadow-lg shadow-emerald-500/20 hover:-translate-y-0.5"
110119
>
111-
Explore gigs
120+
Explore Gigs
112121
</Link>
113122
</div>
114123
</DashboardHeader>
115124

116-
<div className="flex-1 w-full overflow-y-auto pb-10">
117-
{children}
125+
<div className="flex-1 w-full relative">
126+
<div className="absolute inset-0 overflow-y-auto">
127+
<div className="min-h-full pb-6">
128+
{children}
129+
</div>
130+
</div>
118131
</div>
119132
</main>
120133

0 commit comments

Comments
 (0)