fix: mobile-first UI redesign - bump all text to 12px+, 44px+ touch targets, reduced content density

This commit is contained in:
root
2026-06-15 11:07:41 +02:00
parent e479df82e2
commit 8f0ff9d47a
16 changed files with 192 additions and 143 deletions
+7 -7
View File
@@ -248,7 +248,7 @@ export default function ThreadDetailPage() {
<Star size={12} className="text-[#D4AF37]" /> <Star size={12} className="text-[#D4AF37]" />
)} )}
</div> </div>
<div className="flex items-center gap-1.5 text-[10px] text-gray-600"> <div className="flex items-center gap-1.5 text-xs text-gray-600">
<span className="text-gray-500">{thread.category.name}</span> <span className="text-gray-500">{thread.category.name}</span>
<span>·</span> <span>·</span>
<span>{timeAgo(thread.createdAt)}</span> <span>{timeAgo(thread.createdAt)}</span>
@@ -259,7 +259,7 @@ export default function ThreadDetailPage() {
const Icon = SHARIAH_LABELS[thread.shariahStatus].icon; const Icon = SHARIAH_LABELS[thread.shariahStatus].icon;
return <Icon size={9} />; return <Icon size={9} />;
})()} })()}
<span className="text-[9px]">{SHARIAH_LABELS[thread.shariahStatus].label}</span> <span className="text-[10px]">{SHARIAH_LABELS[thread.shariahStatus].label}</span>
</div> </div>
</div> </div>
</div> </div>
@@ -310,7 +310,7 @@ export default function ThreadDetailPage() {
)} )}
</div> </div>
</div> </div>
<div className="flex items-center gap-1 text-[10px] text-gray-600"> <div className="flex items-center gap-1 text-xs text-gray-600">
<Clock size={9} /> <Clock size={9} />
<span>{timeAgo(post.createdAt)}</span> <span>{timeAgo(post.createdAt)}</span>
</div> </div>
@@ -324,7 +324,7 @@ export default function ThreadDetailPage() {
{/* Shariah compliance label */} {/* Shariah compliance label */}
<div className={`flex items-center gap-0.5 ${shariahInfo.color}`}> <div className={`flex items-center gap-0.5 ${shariahInfo.color}`}>
<ShariahIcon size={9} /> <ShariahIcon size={9} />
<span className="text-[9px]">{shariahInfo.label}</span> <span className="text-[10px]">{shariahInfo.label}</span>
</div> </div>
</div> </div>
); );
@@ -342,7 +342,7 @@ export default function ThreadDetailPage() {
</p> </p>
<button <button
onClick={() => router.push("/profile")} onClick={() => router.push("/profile")}
className="inline-flex items-center gap-1.5 bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-xl px-4 py-2 text-xs font-medium text-[#D4AF37] active:bg-[#D4AF37]/25 transition" className="inline-flex items-center gap-1.5 bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-xl px-4 py-3 text-xs font-medium text-[#D4AF37] active:bg-[#D4AF37]/25 transition"
> >
<Crown size={12} /> <Crown size={12} />
Upgrade Now Upgrade Now
@@ -360,13 +360,13 @@ export default function ThreadDetailPage() {
className="w-full bg-transparent px-4 py-3 text-sm text-white placeholder-gray-600 focus:outline-none resize-none" className="w-full bg-transparent px-4 py-3 text-sm text-white placeholder-gray-600 focus:outline-none resize-none"
/> />
<div className="flex items-center justify-between px-4 pb-3"> <div className="flex items-center justify-between px-4 pb-3">
<span className="text-[10px] text-gray-600"> <span className="text-xs text-gray-600">
{replyContent.length}/5000 {replyContent.length}/5000
</span> </span>
<button <button
type="submit" type="submit"
disabled={submitting || !replyContent.trim()} disabled={submitting || !replyContent.trim()}
className="flex items-center gap-1.5 bg-[#D4AF37] text-[#0a0a0f] rounded-xl px-4 py-2 text-xs font-semibold transition active:bg-[#c5a233] disabled:opacity-50" className="flex items-center gap-1.5 bg-[#D4AF37] text-[#0a0a0f] rounded-xl px-4 py-3 text-xs font-semibold transition active:bg-[#c5a233] disabled:opacity-50"
> >
{submitting ? ( {submitting ? (
<> <>
+14 -14
View File
@@ -222,7 +222,7 @@ export default function ForumPage() {
</div> </div>
<div> <div>
<h1 className="text-lg font-bold text-white">Forum</h1> <h1 className="text-lg font-bold text-white">Forum</h1>
<p className="text-[10px] text-gray-500">Community Discussions</p> <p className="text-xs text-gray-500">Community Discussions</p>
</div> </div>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@@ -237,7 +237,7 @@ export default function ForumPage() {
setCreateError(null); setCreateError(null);
setShowCreateModal(true); setShowCreateModal(true);
}} }}
className="flex items-center gap-1.5 bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-xl px-3 py-2 active:bg-[#D4AF37]/25 transition" className="flex items-center gap-1.5 bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-xl px-3 py-3 active:bg-[#D4AF37]/25 transition"
> >
<Plus size={14} className="text-[#D4AF37]" /> <Plus size={14} className="text-[#D4AF37]" />
<span className="text-xs font-medium text-[#D4AF37]">New Thread</span> <span className="text-xs font-medium text-[#D4AF37]">New Thread</span>
@@ -253,7 +253,7 @@ export default function ForumPage() {
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Lock size={14} className="text-[#D4AF37] shrink-0" /> <Lock size={14} className="text-[#D4AF37] shrink-0" />
<div className="flex-1"> <div className="flex-1">
<p className="text-[11px] text-amber-300/90"> <p className="text-xs text-amber-300/90">
<span className="font-semibold">Free</span> members can browse.{" "} <span className="font-semibold">Free</span> members can browse.{" "}
<span className="text-[#D4AF37] font-semibold">Premium</span> or{" "} <span className="text-[#D4AF37] font-semibold">Premium</span> or{" "}
<span className="text-purple-400 font-semibold">Pro</span> required to post. <span className="text-purple-400 font-semibold">Pro</span> required to post.
@@ -261,7 +261,7 @@ export default function ForumPage() {
</div> </div>
<button <button
onClick={() => router.push("/profile")} onClick={() => router.push("/profile")}
className="text-[10px] font-semibold text-[#D4AF37] bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-lg px-2.5 py-1.5 active:bg-[#D4AF37]/25 transition" className="text-xs font-semibold text-[#D4AF37] bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-lg px-2.5 py-3 active:bg-[#D4AF37]/25 transition"
> >
Upgrade Upgrade
</button> </button>
@@ -278,7 +278,7 @@ export default function ForumPage() {
placeholder="Search threads..." placeholder="Search threads..."
value={searchQuery} value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)} onChange={(e) => setSearchQuery(e.target.value)}
className="w-full bg-[#111118] border border-gray-800/60 rounded-xl pl-10 pr-4 py-2.5 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition" className="w-full bg-[#111118] border border-gray-800/60 rounded-xl pl-10 pr-4 py-3 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition"
/> />
</div> </div>
</div> </div>
@@ -363,7 +363,7 @@ export default function ForumPage() {
setCreateError(null); setCreateError(null);
setShowCreateModal(true); setShowCreateModal(true);
}} }}
className="mt-4 flex items-center gap-2 bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-xl px-4 py-2.5 active:bg-[#D4AF37]/25 transition" className="mt-4 flex items-center gap-2 bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-xl px-4 py-3 active:bg-[#D4AF37]/25 transition"
> >
<Plus size={16} className="text-[#D4AF37]" /> <Plus size={16} className="text-[#D4AF37]" />
<span className="text-sm font-medium text-[#D4AF37]">Start Discussion</span> <span className="text-sm font-medium text-[#D4AF37]">Start Discussion</span>
@@ -395,7 +395,7 @@ export default function ForumPage() {
</div> </div>
{/* Meta row */} {/* Meta row */}
<div className="flex flex-wrap items-center gap-x-2 gap-y-1 text-[10px] text-gray-600"> <div className="flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-gray-600">
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">
<span className="text-gray-500">by</span> <span className="text-gray-500">by</span>
<span className={`font-medium ${ <span className={`font-medium ${
@@ -431,12 +431,12 @@ export default function ForumPage() {
<div className="flex items-center gap-2 mt-1.5"> <div className="flex items-center gap-2 mt-1.5">
<div className={`flex items-center gap-0.5 ${shariahInfo.color}`}> <div className={`flex items-center gap-0.5 ${shariahInfo.color}`}>
<ShariahIcon size={9} /> <ShariahIcon size={9} />
<span className="text-[9px]">{shariahInfo.label}</span> <span className="text-[10px]">{shariahInfo.label}</span>
</div> </div>
<span className="text-gray-700">·</span> <span className="text-gray-700">·</span>
<div className="flex items-center gap-0.5 text-gray-600"> <div className="flex items-center gap-0.5 text-gray-600">
<Clock size={9} /> <Clock size={9} />
<span className="text-[9px]">{timeAgo(thread.createdAt)}</span> <span className="text-xs">{timeAgo(thread.createdAt)}</span>
</div> </div>
</div> </div>
</div> </div>
@@ -480,7 +480,7 @@ export default function ForumPage() {
setCreateForm((f) => ({ ...f, categoryId: e.target.value })) setCreateForm((f) => ({ ...f, categoryId: e.target.value }))
} }
required required
className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl px-3.5 py-2.5 text-sm text-white focus:outline-none focus:border-[#D4AF37]/40 transition appearance-none" className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl px-3.5 py-3 text-sm text-white focus:outline-none focus:border-[#D4AF37]/40 transition appearance-none"
style={{ style={{
backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E")`, backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E")`,
backgroundRepeat: "no-repeat", backgroundRepeat: "no-repeat",
@@ -508,7 +508,7 @@ export default function ForumPage() {
placeholder="What's on your mind?" placeholder="What's on your mind?"
required required
maxLength={200} maxLength={200}
className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl px-3.5 py-2.5 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition" className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl px-3.5 py-3 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition"
/> />
</div> </div>
@@ -525,7 +525,7 @@ export default function ForumPage() {
required required
maxLength={10000} maxLength={10000}
rows={5} rows={5}
className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl px-3.5 py-2.5 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition resize-none" className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl px-3.5 py-3 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition resize-none"
/> />
</div> </div>
@@ -539,14 +539,14 @@ export default function ForumPage() {
<button <button
type="button" type="button"
onClick={() => setShowCreateModal(false)} onClick={() => setShowCreateModal(false)}
className="flex-1 py-2.5 rounded-xl text-sm font-medium text-gray-500 bg-gray-800/40 border border-gray-800/60 active:bg-gray-700/40 transition" className="flex-1 py-3 rounded-xl text-sm font-medium text-gray-500 bg-gray-800/40 border border-gray-800/60 active:bg-gray-700/40 transition"
> >
Cancel Cancel
</button> </button>
<button <button
type="submit" type="submit"
disabled={creating} disabled={creating}
className="flex-1 py-2.5 rounded-xl text-sm font-semibold text-[#0a0a0f] bg-[#D4AF37] active:bg-[#c5a233] transition flex items-center justify-center gap-2 disabled:opacity-60" className="flex-1 py-3 rounded-xl text-sm font-semibold text-[#0a0a0f] bg-[#D4AF37] active:bg-[#c5a233] transition flex items-center justify-center gap-2 disabled:opacity-60"
> >
{creating ? ( {creating ? (
<> <>
+44 -1
View File
@@ -20,6 +20,12 @@
* { * {
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
box-sizing: border-box;
}
html {
font-size: 16px;
-webkit-text-size-adjust: 100%;
} }
body { body {
@@ -27,15 +33,40 @@ body {
color: var(--text-primary); color: var(--text-primary);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
margin: 0; margin: 0;
padding: 0; padding: 0;
padding-bottom: 80px; padding-bottom: 80px;
min-height: 100dvh; min-height: 100dvh;
line-height: 1.5;
}
/* Mobile-first container: caps content width for comfortable reading */
.mobile-container {
max-width: 480px;
margin: 0 auto;
padding-left: 16px;
padding-right: 16px;
}
@media (min-width: 520px) {
.mobile-container {
padding-left: 24px;
padding-right: 24px;
}
}
/* Force all interactive elements to min 44px touch target */
.touch-target {
min-height: 44px;
display: flex;
align-items: center;
justify-content: center;
} }
/* Scrollbar */ /* Scrollbar */
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 4px; width: 3px;
} }
::-webkit-scrollbar-track { ::-webkit-scrollbar-track {
background: transparent; background: transparent;
@@ -81,3 +112,15 @@ body {
.flame { .flame {
animation: flicker 0.5s ease-in-out infinite; animation: flicker 0.5s ease-in-out infinite;
} }
/* Prevent text size adjustment on orientation change */
html {
-webkit-text-size-adjust: 100%;
}
/* Better readability on OLED screens */
@media (prefers-color-scheme: dark) {
body {
background-color: var(--bg-primary);
}
}
+9 -9
View File
@@ -277,7 +277,7 @@ export default function HalalMonitorPage() {
{usage && ( {usage && (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className="text-right"> <div className="text-right">
<p className="text-[10px] text-gray-500">Today</p> <p className="text-xs text-gray-500">Today</p>
<p className="text-xs font-semibold text-gray-300"> <p className="text-xs font-semibold text-gray-300">
{usage.remaining}/{usage.queriesLimit} {usage.remaining}/{usage.queriesLimit}
</p> </p>
@@ -313,7 +313,7 @@ export default function HalalMonitorPage() {
<p className="text-sm font-semibold text-emerald-400"> <p className="text-sm font-semibold text-emerald-400">
Upgrade for Unlimited Upgrade for Unlimited
</p> </p>
<p className="text-[11px] text-gray-500"> <p className="text-xs text-gray-500">
Unlock restaurants + cafes & unlimited queries Unlock restaurants + cafes & unlimited queries
</p> </p>
</div> </div>
@@ -324,7 +324,7 @@ export default function HalalMonitorPage() {
{/* Free user scope notice */} {/* Free user scope notice */}
{isFree && ( {isFree && (
<div className="mt-2 flex items-center gap-1.5 text-[11px] text-amber-400/70"> <div className="mt-2 flex items-center gap-1.5 text-xs text-amber-400/70">
<Crown size={12} /> <Crown size={12} />
Free tier: mosques only &bull; 10 queries/day Free tier: mosques only &bull; 10 queries/day
</div> </div>
@@ -333,7 +333,7 @@ export default function HalalMonitorPage() {
{/* ── Search Bar ─────────────────────────────────────────────────── */} {/* ── Search Bar ─────────────────────────────────────────────────── */}
<div className="px-4 mb-3"> <div className="px-4 mb-3">
<div className="flex items-center gap-2 bg-[#111118] border border-gray-800/60 rounded-2xl px-4 py-2.5"> <div className="flex items-center gap-2 bg-[#111118] border border-gray-800/60 rounded-2xl px-4 py-3">
<Search size={16} className="text-gray-500 shrink-0" /> <Search size={16} className="text-gray-500 shrink-0" />
<input <input
type="text" type="text"
@@ -397,7 +397,7 @@ export default function HalalMonitorPage() {
<div className="w-10 h-10 rounded-full bg-emerald-500/20 border-2 border-emerald-500/40 flex items-center justify-center animate-pulse"> <div className="w-10 h-10 rounded-full bg-emerald-500/20 border-2 border-emerald-500/40 flex items-center justify-center animate-pulse">
<MapPin size={18} className="text-emerald-400" /> <MapPin size={18} className="text-emerald-400" />
</div> </div>
<span className="text-[10px] text-emerald-500/60 font-medium"> <span className="text-xs text-emerald-500/60 font-medium">
{visiblePlaces.length} places found {visiblePlaces.length} places found
</span> </span>
</div> </div>
@@ -460,7 +460,7 @@ export default function HalalMonitorPage() {
{place.name} {place.name}
</h3> </h3>
<span <span
className={`text-[10px] font-medium px-2 py-0.5 rounded-full shrink-0 ${ className={`text-xs font-medium px-2 py-0.5 rounded-full shrink-0 ${
place.type === "mosque" place.type === "mosque"
? "bg-emerald-500/15 text-emerald-300 border border-emerald-500/30" ? "bg-emerald-500/15 text-emerald-300 border border-emerald-500/30"
: "bg-amber-500/15 text-amber-300 border border-amber-500/30" : "bg-amber-500/15 text-amber-300 border border-amber-500/30"
@@ -480,7 +480,7 @@ export default function HalalMonitorPage() {
{/* Halal badge */} {/* Halal badge */}
{place.halal_certified && ( {place.halal_certified && (
<span className="inline-flex items-center gap-1 text-[10px] font-medium text-emerald-400 bg-emerald-500/10 px-2 py-0.5 rounded-full"> <span className="inline-flex items-center gap-1 text-xs font-medium text-emerald-400 bg-emerald-500/10 px-2 py-0.5 rounded-full">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400" /> <span className="w-1.5 h-1.5 rounded-full bg-emerald-400" />
Halal Certified Halal Certified
</span> </span>
@@ -584,13 +584,13 @@ export default function HalalMonitorPage() {
{/* Coords */} {/* Coords */}
<div className="grid grid-cols-2 gap-3 mb-5"> <div className="grid grid-cols-2 gap-3 mb-5">
<div className="bg-[#0a0a0f] rounded-xl p-3 text-center"> <div className="bg-[#0a0a0f] rounded-xl p-3 text-center">
<p className="text-[10px] text-gray-600">Latitude</p> <p className="text-xs text-gray-600">Latitude</p>
<p className="text-xs text-gray-300 font-mono"> <p className="text-xs text-gray-300 font-mono">
{selectedPlace.lat.toFixed(4)} {selectedPlace.lat.toFixed(4)}
</p> </p>
</div> </div>
<div className="bg-[#0a0a0f] rounded-xl p-3 text-center"> <div className="bg-[#0a0a0f] rounded-xl p-3 text-center">
<p className="text-[10px] text-gray-600">Longitude</p> <p className="text-xs text-gray-600">Longitude</p>
<p className="text-xs text-gray-300 font-mono"> <p className="text-xs text-gray-300 font-mono">
{selectedPlace.lng.toFixed(4)} {selectedPlace.lng.toFixed(4)}
</p> </p>
+3 -7
View File
@@ -2,7 +2,6 @@ import type { Metadata } from "next";
import "./globals.css"; import "./globals.css";
import { AuthProvider } from "@/lib/AuthContext"; import { AuthProvider } from "@/lib/AuthContext";
import BottomNav from "@/components/BottomNav"; import BottomNav from "@/components/BottomNav";
import NotificationBell from "@/components/NotificationBell";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Falah — Islamic Lifestyle", title: "Falah — Islamic Lifestyle",
@@ -20,7 +19,7 @@ export default function RootLayout({
return ( return (
<html lang="en" className="dark"> <html lang="en" className="dark">
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" /> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, maximum-scale=1, user-scalable=no" />
<meta name="theme-color" content="#0a0a0f" /> <meta name="theme-color" content="#0a0a0f" />
<meta name="mobile-web-app-capable" content="yes" /> <meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
@@ -28,11 +27,8 @@ export default function RootLayout({
</head> </head>
<body> <body>
<AuthProvider> <AuthProvider>
<div className="relative"> <div className="mobile-container relative min-h-dvh">
<div className="absolute top-4 right-4 z-40"> <main className="pb-4">{children}</main>
<NotificationBell />
</div>
<main>{children}</main>
</div> </div>
<BottomNav /> <BottomNav />
</AuthProvider> </AuthProvider>
+1 -1
View File
@@ -133,7 +133,7 @@ export default function LoginPage() {
{/* Demo credentials */} {/* Demo credentials */}
<div className="rounded-xl bg-[#111118] border border-gray-800/60 p-3 text-center"> <div className="rounded-xl bg-[#111118] border border-gray-800/60 p-3 text-center">
<p className="text-[10px] text-gray-600 uppercase tracking-wider mb-1"> <p className="text-xs text-gray-600 uppercase tracking-wider mb-1">
Demo Account Demo Account
</p> </p>
<p className="text-xs text-gray-500"> <p className="text-xs text-gray-500">
+8 -8
View File
@@ -214,7 +214,7 @@ function NurChat() {
<Bot size={16} className="text-[#D4AF37]" /> <Bot size={16} className="text-[#D4AF37]" />
Nur AI Nur AI
</h1> </h1>
<p className="text-[10px] text-gray-600"> <p className="text-xs text-gray-600">
{isPro ? "Pro Plan" : isPremium ? "Premium Plan" : "Free Plan"} {isPro ? "Pro Plan" : isPremium ? "Premium Plan" : "Free Plan"}
</p> </p>
</div> </div>
@@ -222,9 +222,9 @@ function NurChat() {
{!isPremium && ( {!isPremium && (
<Link <Link
href="/upgrade" href="/upgrade"
className="flex items-center gap-1.5 bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-full px-3 py-1.5 text-[11px] font-semibold text-[#D4AF37] active:bg-[#D4AF37]/25 transition" className="flex items-center gap-1.5 bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-full px-4 py-2 min-h-[36px] text-xs font-semibold text-[#D4AF37] active:bg-[#D4AF37]/25 transition"
> >
<Sparkles size={12} /> <Sparkles size={14} />
Upgrade Upgrade
</Link> </Link>
)} )}
@@ -248,7 +248,7 @@ function NurChat() {
{/* ── Daily Cap Bar ── */} {/* ── Daily Cap Bar ── */}
<div className="px-4 mt-3"> <div className="px-4 mt-3">
<div className="flex items-center justify-between mb-1.5"> <div className="flex items-center justify-between mb-1.5">
<span className="text-[11px] text-gray-500 font-medium"> <span className="text-xs text-gray-500 font-medium">
{isUnlimited ? ( {isUnlimited ? (
<span className="text-emerald-400 flex items-center gap-1"> <span className="text-emerald-400 flex items-center gap-1">
<CheckCircle2 size={12} /> <CheckCircle2 size={12} />
@@ -259,7 +259,7 @@ function NurChat() {
)} )}
</span> </span>
{!isUnlimited && remaining <= 3 && remaining > 0 && ( {!isUnlimited && remaining <= 3 && remaining > 0 && (
<span className="text-[10px] text-amber-400 font-medium"> <span className="text-xs text-amber-400 font-medium">
{remaining} left {remaining} left
</span> </span>
)} )}
@@ -289,7 +289,7 @@ function NurChat() {
<p className="text-sm font-semibold text-white"> <p className="text-sm font-semibold text-white">
You've hit your daily limit You've hit your daily limit
</p> </p>
<p className="text-[11px] text-gray-500 mt-0.5"> <p className="text-xs text-gray-500 mt-0.5">
Upgrade to Premium for 100 messages/day or Pro for unlimited access. Upgrade to Premium for 100 messages/day or Pro for unlimited access.
</p> </p>
<Link <Link
@@ -448,7 +448,7 @@ function PersonaSelector({
> >
{persona.name} {persona.name}
</span> </span>
<span className="text-[8px] text-center leading-tight text-gray-600 max-w-[72px]"> <span className="text-[10px] text-center leading-tight text-gray-600 max-w-[72px]">
{persona.description} {persona.description}
</span> </span>
{!accessible && ( {!accessible && (
@@ -494,7 +494,7 @@ function MessageBubble({ message, isPremium, isPro }: { message: ChatMessage; is
{message.content} {message.content}
{message.createdAt && ( {message.createdAt && (
<div <div
className={`text-[10px] mt-2 ${ className={`text-xs mt-2 ${
isUser ? "text-[#0a0a0f]/50" : "text-gray-600" isUser ? "text-[#0a0a0f]/50" : "text-gray-600"
}`} }`}
> >
+28 -28
View File
@@ -110,15 +110,15 @@ export default function HomePage() {
<span className={`text-sm font-bold ${currentStreak > 0 ? "text-orange-300" : "text-gray-500"}`}> <span className={`text-sm font-bold ${currentStreak > 0 ? "text-orange-300" : "text-gray-500"}`}>
{currentStreak} {currentStreak}
</span> </span>
<span className="text-[10px] text-gray-500">day</span> <span className="text-xs text-gray-500">day</span>
</div> </div>
</div> </div>
{/* XP Progress Bar */} {/* XP Progress Bar */}
<div className="mt-2"> <div className="mt-2">
<div className="flex items-center justify-between mb-1"> <div className="flex items-center justify-between mb-1">
<span className="text-[10px] text-gray-500">XP Progress</span> <span className="text-xs text-gray-500">XP Progress</span>
<span className="text-[10px] text-gray-500">{currentXp} / {xpToNext} XP</span> <span className="text-xs text-gray-500">{currentXp} / {xpToNext} XP</span>
</div> </div>
<div className="h-1.5 bg-gray-800 rounded-full overflow-hidden"> <div className="h-1.5 bg-gray-800 rounded-full overflow-hidden">
<div <div
@@ -131,14 +131,14 @@ export default function HomePage() {
{/* Premium banner */} {/* Premium banner */}
{!isPremium && ( {!isPremium && (
<Link href="/upgrade" <Link href="/upgrade"
className="mt-3 flex items-center justify-between glass-gold rounded-2xl px-4 py-3 active:opacity-80 transition"> className="mt-3 flex items-center justify-between glass-gold rounded-2xl px-4 py-3.5 active:opacity-80 transition min-h-[44px]">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="w-8 h-8 rounded-full bg-[#D4AF37]/20 flex items-center justify-center"> <div className="w-8 h-8 rounded-full bg-[#D4AF37]/20 flex items-center justify-center">
<Sparkles size={16} className="text-[#D4AF37]" /> <Sparkles size={16} className="text-[#D4AF37]" />
</div> </div>
<div> <div>
<p className="text-sm font-semibold text-[#D4AF37]">Go Premium</p> <p className="text-sm font-semibold text-[#D4AF37]">Go Premium</p>
<p className="text-[11px] text-gray-500">Unlock unlimited AI & more</p> <p className="text-xs text-gray-500">Unlock unlimited AI & more</p>
</div> </div>
</div> </div>
<ChevronRight size={16} className="text-[#D4AF37]" /> <ChevronRight size={16} className="text-[#D4AF37]" />
@@ -147,7 +147,7 @@ export default function HomePage() {
{/* Pro badge */} {/* Pro badge */}
{isPro && ( {isPro && (
<div className="mt-3 flex items-center gap-2 bg-purple-900/20 border border-purple-500/30 rounded-2xl px-4 py-2.5"> <div className="mt-3 flex items-center gap-2 bg-purple-900/20 border border-purple-500/30 rounded-2xl px-4 py-3 min-h-[44px]">
<Crown size={16} className="text-purple-400" /> <Crown size={16} className="text-purple-400" />
<span className="text-sm font-medium text-purple-300">Pro Member Unlimited Everything</span> <span className="text-sm font-medium text-purple-300">Pro Member Unlimited Everything</span>
</div> </div>
@@ -155,27 +155,27 @@ export default function HomePage() {
{/* FLH Earning Rate - shown for premium/pro */} {/* FLH Earning Rate - shown for premium/pro */}
{(isPremium || isPro) && ( {(isPremium || isPro) && (
<div className="mt-2 flex items-center gap-2 bg-gradient-to-r from-[#D4AF37]/10 to-purple-900/10 border border-[#D4AF37]/20 rounded-2xl px-4 py-2"> <div className="mt-2 flex items-center gap-2 bg-gradient-to-r from-[#D4AF37]/10 to-purple-900/10 border border-[#D4AF37]/20 rounded-2xl px-4 py-3 min-h-[44px]">
<TrendingUp size={14} className="text-[#D4AF37]" /> <TrendingUp size={14} className="text-[#D4AF37]" />
<span className="text-xs font-semibold text-[#D4AF37]">2x Earning Active</span> <span className="text-xs font-semibold text-[#D4AF37]">2x Earning Active</span>
<span className="text-[10px] text-gray-500"> Earn double FLH on marketplace sales</span> <span className="text-xs text-gray-500"> Earn double FLH on marketplace sales</span>
</div> </div>
)} )}
</div> </div>
{/* Daily Verse */} {/* Daily Verse */}
<div className="mx-4 mb-5 bg-gradient-to-br from-emerald-900/20 to-[#111118] border border-emerald-800/30 rounded-2xl p-4"> <div className="mx-4 mb-5 bg-gradient-to-br from-emerald-900/20 to-[#111118] border border-emerald-800/30 rounded-2xl p-5">
<div className="flex items-center gap-2 mb-2"> <div className="flex items-center gap-2 mb-3">
<BookOpen size={14} className="text-emerald-400" /> <BookOpen size={14} className="text-emerald-400" />
<span className="text-xs font-medium text-emerald-400">Daily Verse</span> <span className="text-xs font-medium text-emerald-400">Daily Verse</span>
</div> </div>
<p className="text-lg text-center font-arabic text-emerald-100 mb-2" dir="rtl"> <p className="text-lg text-center font-arabic text-emerald-100 mb-3" dir="rtl">
{verse.arabic} {verse.arabic}
</p> </p>
<p className="text-sm text-gray-400 text-center italic"> <p className="text-sm text-gray-400 text-center italic">
&ldquo;{verse.translation}&rdquo; &ldquo;{verse.translation}&rdquo;
</p> </p>
<p className="text-[10px] text-gray-600 text-center mt-1"> {verse.reference}</p> <p className="text-xs text-gray-600 text-center mt-2"> {verse.reference}</p>
</div> </div>
{/* Streak Reward Card */} {/* Streak Reward Card */}
@@ -184,7 +184,7 @@ export default function HomePage() {
canClaim canClaim
? "from-orange-900/20 to-amber-900/10 border-orange-700/30" ? "from-orange-900/20 to-amber-900/10 border-orange-700/30"
: "from-gray-900/30 to-gray-800/10 border-gray-800/30" : "from-gray-900/30 to-gray-800/10 border-gray-800/30"
} border rounded-2xl p-4`}> } border rounded-2xl p-5`}>
<div className="flex items-center justify-between mb-3"> <div className="flex items-center justify-between mb-3">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className={`w-9 h-9 rounded-xl ${canClaim ? "bg-orange-900/40" : "bg-gray-800/40"} flex items-center justify-center`}> <div className={`w-9 h-9 rounded-xl ${canClaim ? "bg-orange-900/40" : "bg-gray-800/40"} flex items-center justify-center`}>
@@ -192,7 +192,7 @@ export default function HomePage() {
</div> </div>
<div> <div>
<h3 className="text-sm font-semibold text-white">Daily Reward</h3> <h3 className="text-sm font-semibold text-white">Daily Reward</h3>
<p className="text-[10px] text-gray-500"> <p className="text-xs text-gray-500">
{canClaim {canClaim
? `Claim your streak reward — +${todayReward} FLH` ? `Claim your streak reward — +${todayReward} FLH`
: "Reward claimed — come back tomorrow!"} : "Reward claimed — come back tomorrow!"}
@@ -201,7 +201,7 @@ export default function HomePage() {
</div> </div>
<div className="text-right"> <div className="text-right">
<p className="text-lg font-bold text-orange-400">{todayReward.toLocaleString()}</p> <p className="text-lg font-bold text-orange-400">{todayReward.toLocaleString()}</p>
<p className="text-[9px] text-gray-600">FLH reward</p> <p className="text-[10px] text-gray-600">FLH reward</p>
</div> </div>
</div> </div>
@@ -210,12 +210,12 @@ export default function HomePage() {
<button <button
onClick={handleClaimReward} onClick={handleClaimReward}
disabled={claiming} disabled={claiming}
className="w-full py-2.5 bg-gradient-to-r from-orange-600 to-amber-600 hover:from-orange-500 hover:to-amber-500 disabled:opacity-50 text-white text-sm font-semibold rounded-xl active:scale-[0.98] transition-all" className="w-full py-3.5 bg-gradient-to-r from-orange-600 to-amber-600 hover:from-orange-500 hover:to-amber-500 disabled:opacity-50 text-white text-sm font-semibold rounded-xl active:scale-[0.98] transition-all min-h-[44px]"
> >
{claiming ? "Claiming..." : "🔥 Claim Streak Reward"} {claiming ? "Claiming..." : "🔥 Claim Streak Reward"}
</button> </button>
) : ( ) : (
<div className="w-full py-2.5 bg-gray-800/50 text-gray-500 text-sm font-medium rounded-xl text-center"> <div className="w-full py-3.5 bg-gray-800/50 text-gray-500 text-sm font-medium rounded-xl text-center min-h-[44px] flex items-center justify-center">
Claimed Claimed
</div> </div>
)} )}
@@ -228,7 +228,7 @@ export default function HomePage() {
)} )}
{/* XP hint */} {/* XP hint */}
<p className="text-[10px] text-gray-700 text-center mt-2"> <p className="text-xs text-gray-700 text-center mt-3">
+{Math.min(10 + currentStreak * 2, 100)} XP also awarded on claim +{Math.min(10 + currentStreak * 2, 100)} XP also awarded on claim
</p> </p>
</div> </div>
@@ -237,17 +237,17 @@ export default function HomePage() {
{/* Quick Actions */} {/* Quick Actions */}
<div className="px-4 mb-5"> <div className="px-4 mb-5">
<h2 className="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3">Quick Actions</h2> <h2 className="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3">Quick Actions</h2>
<div className="grid grid-cols-4 gap-3"> <div className="grid grid-cols-2 gap-4">
<QuickAction href="/nur" icon={Bot} label="Nur AI" color="bg-amber-900/30 text-amber-300" /> <QuickAction href="/nur" icon={Bot} label="Nur AI" color="bg-amber-900/30 text-amber-300" />
<QuickAction href="/souq" icon={ShoppingBag} label="Souq" color="bg-[#D4AF37]/15 text-[#D4AF37]" /> <QuickAction href="/souq" icon={ShoppingBag} label="Souq" color="bg-[#D4AF37]/15 text-[#D4AF37]" />
<QuickAction href="/halal-monitor" icon={MapPin} label="Halal" color="bg-emerald-900/30 text-emerald-300" /> <QuickAction href="/halal-monitor" icon={MapPin} label="Halal Monitor" color="bg-emerald-900/30 text-emerald-300" />
<QuickAction href="/wallet" icon={Wallet} label="Wallet" color="bg-blue-900/30 text-blue-300" /> <QuickAction href="/wallet" icon={Wallet} label="Wallet" color="bg-blue-900/30 text-blue-300" />
</div> </div>
</div> </div>
{/* Stats Row */} {/* Stats Row */}
<div className="mx-4 mb-5"> <div className="mx-4 mb-5">
<div className="grid grid-cols-3 gap-3"> <div className="flex gap-3">
<StatCard label="FLH Balance" value={user.flhBalance.toLocaleString()} icon={Zap} color="text-[#D4AF37]" /> <StatCard label="FLH Balance" value={user.flhBalance.toLocaleString()} icon={Zap} color="text-[#D4AF37]" />
<StatCard label="AI Today" value={`${user.dailyMsgCount}/10`} icon={Bot} color="text-amber-400" /> <StatCard label="AI Today" value={`${user.dailyMsgCount}/10`} icon={Bot} color="text-amber-400" />
<StatCard label="Tier" value={isPro ? "Pro" : isPremium ? "Premium" : "Free"} icon={Crown} <StatCard label="Tier" value={isPro ? "Pro" : isPremium ? "Premium" : "Free"} icon={Crown}
@@ -259,7 +259,7 @@ export default function HomePage() {
<div className="px-4"> <div className="px-4">
<div className="flex items-center justify-between mb-3"> <div className="flex items-center justify-between mb-3">
<h2 className="text-xs font-semibold text-gray-500 uppercase tracking-wider">Activity</h2> <h2 className="text-xs font-semibold text-gray-500 uppercase tracking-wider">Activity</h2>
<Link href="/forum" className="text-[11px] text-[#D4AF37]">View all</Link> <Link href="/forum" className="text-xs text-[#D4AF37] min-h-[44px] inline-flex items-center">View all</Link>
</div> </div>
<div className="bg-[#111118] border border-gray-800/60 rounded-2xl p-5 text-center"> <div className="bg-[#111118] border border-gray-800/60 rounded-2xl p-5 text-center">
<MessageCircle size={24} className="mx-auto text-gray-700 mb-2" /> <MessageCircle size={24} className="mx-auto text-gray-700 mb-2" />
@@ -270,7 +270,7 @@ export default function HomePage() {
{/* Premium upsell at bottom for free users */} {/* Premium upsell at bottom for free users */}
{!isPremium && ( {!isPremium && (
<div className="mx-4 mt-5 bg-gradient-to-r from-[#D4AF37]/10 to-purple-900/10 border border-[#D4AF37]/20 rounded-2xl p-4 relative overflow-hidden"> <div className="mx-4 mt-5 bg-gradient-to-r from-[#D4AF37]/10 to-purple-900/10 border border-[#D4AF37]/20 rounded-2xl p-5 relative overflow-hidden">
<div className="absolute top-0 right-0 w-24 h-24 bg-[#D4AF37]/5 rounded-full -translate-y-1/2 translate-x-1/2 blur-2xl" /> <div className="absolute top-0 right-0 w-24 h-24 bg-[#D4AF37]/5 rounded-full -translate-y-1/2 translate-x-1/2 blur-2xl" />
<div className="flex items-start gap-3 relative"> <div className="flex items-start gap-3 relative">
<div className="w-10 h-10 rounded-2xl bg-[#D4AF37]/15 flex items-center justify-center shrink-0"> <div className="w-10 h-10 rounded-2xl bg-[#D4AF37]/15 flex items-center justify-center shrink-0">
@@ -283,7 +283,7 @@ export default function HomePage() {
</h3> </h3>
<p className="text-xs text-gray-500 mt-1">Premium gives you unlimited AI, halal monitor, <strong className="text-gray-400">2x FLH earning</strong>, and marketplace access.</p> <p className="text-xs text-gray-500 mt-1">Premium gives you unlimited AI, halal monitor, <strong className="text-gray-400">2x FLH earning</strong>, and marketplace access.</p>
<Link href="/upgrade" <Link href="/upgrade"
className="inline-block mt-3 text-xs font-semibold text-[#D4AF37] border border-[#D4AF37]/40 rounded-full px-4 py-1.5 active:bg-[#D4AF37]/10 transition hover:shadow-[0_0_12px_rgba(212,175,55,0.3)]"> className="inline-block mt-3 text-xs font-semibold text-[#D4AF37] border border-[#D4AF37]/40 rounded-full px-6 py-3 active:bg-[#D4AF37]/10 transition hover:shadow-[0_0_12px_rgba(212,175,55,0.3)] min-h-[44px] leading-tight">
See Plans See Plans
</Link> </Link>
</div> </div>
@@ -300,17 +300,17 @@ function QuickAction({ href, icon: Icon, label, color }: { href: string; icon: a
<div className={`w-14 h-14 rounded-2xl flex items-center justify-center ${color} bg-opacity-20`}> <div className={`w-14 h-14 rounded-2xl flex items-center justify-center ${color} bg-opacity-20`}>
<Icon size={22} /> <Icon size={22} />
</div> </div>
<span className="text-[10px] text-gray-500 font-medium">{label}</span> <span className="text-xs text-gray-500 font-medium">{label}</span>
</Link> </Link>
); );
} }
function StatCard({ label, value, icon: Icon, color }: { label: string; value: string; icon: any; color: string }) { function StatCard({ label, value, icon: Icon, color }: { label: string; value: string; icon: any; color: string }) {
return ( return (
<div className="bg-[#111118] border border-gray-800/60 rounded-2xl p-3 text-center"> <div className="flex-1 bg-[#111118] border border-gray-800/60 rounded-2xl p-3 text-center">
<Icon size={14} className={`mx-auto mb-1 ${color}`} /> <Icon size={16} className={`mx-auto mb-1 ${color}`} />
<p className="text-sm font-bold text-white">{value}</p> <p className="text-sm font-bold text-white">{value}</p>
<p className="text-[9px] text-gray-600 mt-0.5">{label}</p> <p className="text-[10px] text-gray-600 mt-0.5">{label}</p>
</div> </div>
); );
} }
+13 -13
View File
@@ -187,7 +187,7 @@ export default function ProfilePage() {
}`}> }`}>
{tier === "pro" ? "Pro Member" : "Premium Member"} {tier === "pro" ? "Pro Member" : "Premium Member"}
</p> </p>
<p className="text-[10px] text-gray-500 mt-0.5"> <p className="text-xs text-gray-500 mt-0.5">
{tier === "pro" {tier === "pro"
? "Unlimited everything + 0% marketplace fees" ? "Unlimited everything + 0% marketplace fees"
: "Enhanced AI + marketplace access"} : "Enhanced AI + marketplace access"}
@@ -253,7 +253,7 @@ export default function ProfilePage() {
type="text" type="text"
value={name} value={name}
onChange={(e) => setName(e.target.value)} onChange={(e) => setName(e.target.value)}
className="w-full bg-[#1a1a24] border border-gray-800/60 rounded-xl px-4 py-3 text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/50 focus:ring-1 focus:ring-[#D4AF37]/30 transition" className="w-full bg-[#1a1a24] border border-gray-800/60 rounded-xl px-4 py-4 text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/50 focus:ring-1 focus:ring-[#D4AF37]/30 transition min-h-[48px]"
/> />
</div> </div>
@@ -267,7 +267,7 @@ export default function ProfilePage() {
value={preferredName} value={preferredName}
onChange={(e) => setPreferredName(e.target.value)} onChange={(e) => setPreferredName(e.target.value)}
placeholder="How Nur AI should address you" placeholder="How Nur AI should address you"
className="w-full bg-[#1a1a24] border border-gray-800/60 rounded-xl px-4 py-3 text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/50 focus:ring-1 focus:ring-[#D4AF37]/30 transition" className="w-full bg-[#1a1a24] border border-gray-800/60 rounded-xl px-4 py-4 text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/50 focus:ring-1 focus:ring-[#D4AF37]/30 transition min-h-[48px]"
/> />
</div> </div>
@@ -279,7 +279,7 @@ export default function ProfilePage() {
<select <select
value={coachPersona} value={coachPersona}
onChange={(e) => setCoachPersona(e.target.value)} onChange={(e) => setCoachPersona(e.target.value)}
className="w-full bg-[#1a1a24] border border-gray-800/60 rounded-xl px-4 py-3 text-white focus:outline-none focus:border-[#D4AF37]/50 focus:ring-1 focus:ring-[#D4AF37]/30 transition appearance-none" className="w-full bg-[#1a1a24] border border-gray-800/60 rounded-xl px-4 py-4 text-white focus:outline-none focus:border-[#D4AF37]/50 focus:ring-1 focus:ring-[#D4AF37]/30 transition appearance-none min-h-[48px]"
> >
<option value="">Default</option> <option value="">Default</option>
{PERSONAS.map((p) => ( {PERSONAS.map((p) => (
@@ -298,7 +298,7 @@ export default function ProfilePage() {
<select <select
value={madhab} value={madhab}
onChange={(e) => setMadhab(e.target.value)} onChange={(e) => setMadhab(e.target.value)}
className="w-full bg-[#1a1a24] border border-gray-800/60 rounded-xl px-4 py-3 text-white focus:outline-none focus:border-[#D4AF37]/50 focus:ring-1 focus:ring-[#D4AF37]/30 transition appearance-none" className="w-full bg-[#1a1a24] border border-gray-800/60 rounded-xl px-4 py-4 text-white focus:outline-none focus:border-[#D4AF37]/50 focus:ring-1 focus:ring-[#D4AF37]/30 transition appearance-none min-h-[48px]"
> >
<option value="">Not specified</option> <option value="">Not specified</option>
{VALID_MADHABS.map((m) => ( {VALID_MADHABS.map((m) => (
@@ -319,14 +319,14 @@ export default function ProfilePage() {
onChange={(e) => setCoachingGoals(e.target.value)} onChange={(e) => setCoachingGoals(e.target.value)}
placeholder="What would you like to work on?" placeholder="What would you like to work on?"
rows={3} rows={3}
className="w-full bg-[#1a1a24] border border-gray-800/60 rounded-xl px-4 py-3 text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/50 focus:ring-1 focus:ring-[#D4AF37]/30 transition resize-none" className="w-full bg-[#1a1a24] border border-gray-800/60 rounded-xl px-4 py-4 text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/50 focus:ring-1 focus:ring-[#D4AF37]/30 transition resize-none min-h-[48px]"
/> />
</div> </div>
<button <button
type="submit" type="submit"
disabled={saving} disabled={saving}
className="w-full flex items-center justify-center gap-2 py-3 rounded-xl bg-[#D4AF37] text-[#0a0a0f] font-semibold text-sm active:opacity-80 disabled:opacity-50 transition" className="w-full flex items-center justify-center gap-2 py-4 rounded-xl bg-[#D4AF37] text-[#0a0a0f] font-semibold text-sm active:opacity-80 disabled:opacity-50 transition min-h-[48px]"
> >
{saving ? ( {saving ? (
<> <>
@@ -384,7 +384,7 @@ export default function ProfilePage() {
<div className="mt-4 pt-3 border-t border-gray-800/60"> <div className="mt-4 pt-3 border-t border-gray-800/60">
<Link <Link
href="/upgrade" href="/upgrade"
className="flex items-center justify-between py-2 px-3 rounded-xl bg-[#D4AF37]/10 border border-[#D4AF37]/20 active:bg-[#D4AF37]/20 transition" className="flex items-center justify-between py-3 px-4 rounded-xl bg-[#D4AF37]/10 border border-[#D4AF37]/20 active:bg-[#D4AF37]/20 transition"
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<ExternalLink size={14} className="text-[#D4AF37]" /> <ExternalLink size={14} className="text-[#D4AF37]" />
@@ -395,16 +395,16 @@ export default function ProfilePage() {
<ChevronRight size={14} className="text-[#D4AF37]" /> <ChevronRight size={14} className="text-[#D4AF37]" />
</Link> </Link>
{user.trialEndsAt && ( {user.trialEndsAt && (
<div className="mt-2 flex items-center gap-1.5 px-3 py-1.5"> <div className="mt-2 flex items-center gap-2 px-3 py-2.5">
<span className="text-[10px] text-gray-600"> <span className="text-xs text-gray-600">
Trial ends{" "} Trial ends{" "}
{new Date(user.trialEndsAt).toLocaleDateString("en-MY", { {new Date(user.trialEndsAt).toLocaleDateString("en-MY", {
month: "short", month: "short",
day: "numeric", day: "numeric",
})} })}
</span> </span>
<span className="text-[10px] text-gray-700">·</span> <span className="text-xs text-gray-700">·</span>
<span className="text-[10px] text-amber-400 font-medium"> <span className="text-xs text-amber-400 font-medium">
{Math.max(0, Math.ceil((new Date(user.trialEndsAt).getTime() - Date.now()) / (1000 * 60 * 60 * 24)))} days remaining {Math.max(0, Math.ceil((new Date(user.trialEndsAt).getTime() - Date.now()) / (1000 * 60 * 60 * 24)))} days remaining
</span> </span>
</div> </div>
@@ -416,7 +416,7 @@ export default function ProfilePage() {
{/* Logout */} {/* Logout */}
<button <button
onClick={handleLogout} onClick={handleLogout}
className="w-full flex items-center justify-between py-3.5 px-5 rounded-xl bg-red-900/10 border border-red-800/30 text-red-400 active:bg-red-900/20 transition" className="w-full flex items-center justify-between py-3.5 px-5 rounded-xl bg-red-900/10 border border-red-800/30 text-red-400 active:bg-red-900/20 transition min-h-[48px]"
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<LogOut size={16} /> <LogOut size={16} />
+1 -1
View File
@@ -152,7 +152,7 @@ export default function RegisterPage() {
{/* Bonus info */} {/* Bonus info */}
<div className="mt-6 rounded-xl bg-[#111118] border border-gray-800/60 p-3 text-center"> <div className="mt-6 rounded-xl bg-[#111118] border border-gray-800/60 p-3 text-center">
<p className="text-[10px] text-gray-600 uppercase tracking-wider mb-1"> <p className="text-xs text-gray-600 uppercase tracking-wider mb-1">
New Member Bonus New Member Bonus
</p> </p>
<p className="text-xs text-gray-500"> <p className="text-xs text-gray-500">
+25 -25
View File
@@ -235,7 +235,7 @@ export default function SouqPage() {
</div> </div>
<div> <div>
<h1 className="text-lg font-bold text-white">Souq</h1> <h1 className="text-lg font-bold text-white">Souq</h1>
<p className="text-[10px] text-gray-500">Islamic Marketplace</p> <p className="text-xs text-gray-500">Islamic Marketplace</p>
</div> </div>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@@ -246,7 +246,7 @@ export default function SouqPage() {
setCreateError(null); setCreateError(null);
setShowCreateModal(true); setShowCreateModal(true);
}} }}
className="flex items-center gap-1.5 bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-xl px-3 py-2 active:bg-[#D4AF37]/25 transition" className="flex items-center gap-1.5 bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-xl px-3 py-3 active:bg-[#D4AF37]/25 transition"
> >
<Plus size={14} className="text-[#D4AF37]" /> <Plus size={14} className="text-[#D4AF37]" />
<span className="text-xs font-medium text-[#D4AF37]">Sell</span> <span className="text-xs font-medium text-[#D4AF37]">Sell</span>
@@ -257,7 +257,7 @@ export default function SouqPage() {
<span className="text-xs font-bold text-white"> <span className="text-xs font-bold text-white">
{user.flhBalance.toLocaleString()} {user.flhBalance.toLocaleString()}
</span> </span>
<span className="text-[9px] text-gray-600">FLH</span> <span className="text-xs text-gray-600">FLH</span>
</div> </div>
</div> </div>
</div> </div>
@@ -267,7 +267,7 @@ export default function SouqPage() {
<div className="mx-4 mb-3 bg-gradient-to-r from-amber-900/15 to-gray-900/50 border border-amber-800/20 rounded-xl px-3 py-2"> <div className="mx-4 mb-3 bg-gradient-to-r from-amber-900/15 to-gray-900/50 border border-amber-800/20 rounded-xl px-3 py-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<AlertTriangle size={12} className="text-amber-400 shrink-0" /> <AlertTriangle size={12} className="text-amber-400 shrink-0" />
<p className="text-[10px] text-amber-300/80"> <p className="text-xs text-amber-300/80">
Platform fee: 1.5% for standard listings, <strong>0% for Pro sellers</strong>. Platform fee: 1.5% for standard listings, <strong>0% for Pro sellers</strong>.
All prices in FLH (Falah Coins). All prices in FLH (Falah Coins).
</p> </p>
@@ -283,7 +283,7 @@ export default function SouqPage() {
placeholder="Search listings..." placeholder="Search listings..."
value={searchQuery} value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)} onChange={(e) => setSearchQuery(e.target.value)}
className="w-full bg-[#111118] border border-gray-800/60 rounded-xl pl-10 pr-4 py-2.5 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition" className="w-full bg-[#111118] border border-gray-800/60 rounded-xl pl-10 pr-4 py-3 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition"
/> />
</div> </div>
</div> </div>
@@ -354,7 +354,7 @@ export default function SouqPage() {
setCreateError(null); setCreateError(null);
setShowCreateModal(true); setShowCreateModal(true);
}} }}
className="mt-4 flex items-center gap-2 bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-xl px-4 py-2.5 active:bg-[#D4AF37]/25 transition" className="mt-4 flex items-center gap-2 bg-[#D4AF37]/15 border border-[#D4AF37]/30 rounded-xl px-4 py-3 active:bg-[#D4AF37]/25 transition"
> >
<Plus size={16} className="text-[#D4AF37]" /> <Plus size={16} className="text-[#D4AF37]" />
<span className="text-sm font-medium text-[#D4AF37]">Create Listing</span> <span className="text-sm font-medium text-[#D4AF37]">Create Listing</span>
@@ -410,7 +410,7 @@ export default function SouqPage() {
placeholder="e.g. Tafsir Ibn Kathir PDF" placeholder="e.g. Tafsir Ibn Kathir PDF"
required required
maxLength={100} maxLength={100}
className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl px-3.5 py-2.5 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition" className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl px-3.5 py-3 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition"
/> />
</div> </div>
@@ -427,7 +427,7 @@ export default function SouqPage() {
required required
maxLength={2000} maxLength={2000}
rows={3} rows={3}
className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl px-3.5 py-2.5 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition resize-none" className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl px-3.5 py-3 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition resize-none"
/> />
</div> </div>
@@ -440,7 +440,7 @@ export default function SouqPage() {
onChange={(e) => onChange={(e) =>
setCreateForm((f) => ({ ...f, category: e.target.value })) setCreateForm((f) => ({ ...f, category: e.target.value }))
} }
className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl px-3.5 py-2.5 text-sm text-white focus:outline-none focus:border-[#D4AF37]/40 transition appearance-none" className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl px-3.5 py-3 text-sm text-white focus:outline-none focus:border-[#D4AF37]/40 transition appearance-none"
style={{ style={{
backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E")`, backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E")`,
backgroundRepeat: "no-repeat", backgroundRepeat: "no-repeat",
@@ -469,7 +469,7 @@ export default function SouqPage() {
placeholder="100" placeholder="100"
required required
min={1} min={1}
className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl pl-3.5 pr-10 py-2.5 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition" className="w-full bg-[#0a0a0f] border border-gray-800/60 rounded-xl pl-3.5 pr-10 py-3 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/40 transition"
/> />
<span className="absolute right-3.5 top-1/2 -translate-y-1/2 text-xs font-medium text-[#D4AF37]"> <span className="absolute right-3.5 top-1/2 -translate-y-1/2 text-xs font-medium text-[#D4AF37]">
FLH FLH
@@ -487,14 +487,14 @@ export default function SouqPage() {
<button <button
type="button" type="button"
onClick={() => setShowCreateModal(false)} onClick={() => setShowCreateModal(false)}
className="flex-1 py-2.5 rounded-xl text-sm font-medium text-gray-500 bg-gray-800/40 border border-gray-800/60 active:bg-gray-700/40 transition" className="flex-1 py-3 rounded-xl text-sm font-medium text-gray-500 bg-gray-800/40 border border-gray-800/60 active:bg-gray-700/40 transition"
> >
Cancel Cancel
</button> </button>
<button <button
type="submit" type="submit"
disabled={creating} disabled={creating}
className="flex-1 py-2.5 rounded-xl text-sm font-semibold text-[#0a0a0f] bg-[#D4AF37] active:bg-[#c5a233] transition flex items-center justify-center gap-2 disabled:opacity-60" className="flex-1 py-3 rounded-xl text-sm font-semibold text-[#0a0a0f] bg-[#D4AF37] active:bg-[#c5a233] transition flex items-center justify-center gap-2 disabled:opacity-60"
> >
{creating ? ( {creating ? (
<> <>
@@ -548,7 +548,7 @@ export default function SouqPage() {
setShowConfirmDialog(null); setShowConfirmDialog(null);
setPurchaseResult(null); setPurchaseResult(null);
}} }}
className="w-full py-2.5 rounded-xl text-sm font-semibold text-[#0a0a0f] bg-[#D4AF37] active:bg-[#c5a233] transition" className="w-full py-3 rounded-xl text-sm font-semibold text-[#0a0a0f] bg-[#D4AF37] active:bg-[#c5a233] transition"
> >
Close Close
</button> </button>
@@ -572,12 +572,12 @@ export default function SouqPage() {
<span className="text-xs text-gray-600">FLH</span> <span className="text-xs text-gray-600">FLH</span>
</div> </div>
<div className="flex items-center gap-1.5 mt-2"> <div className="flex items-center gap-1.5 mt-2">
<span className="text-[10px] text-gray-500">From:</span> <span className="text-xs text-gray-500">From:</span>
<span className="text-[10px] font-medium text-gray-300"> <span className="text-xs font-medium text-gray-300">
{showConfirmDialog.listing.seller.name} {showConfirmDialog.listing.seller.name}
</span> </span>
{showConfirmDialog.listing.seller.isPro && ( {showConfirmDialog.listing.seller.isPro && (
<span className="flex items-center gap-0.5 text-[9px] text-purple-400"> <span className="flex items-center gap-0.5 text-[10px] text-purple-400">
<Crown size={9} /> Pro <Crown size={9} /> Pro
</span> </span>
)} )}
@@ -621,7 +621,7 @@ export default function SouqPage() {
setPurchaseResult(null); setPurchaseResult(null);
}} }}
disabled={!!purchasingId} disabled={!!purchasingId}
className="flex-1 py-2.5 rounded-xl text-sm font-medium text-gray-500 bg-gray-800/40 border border-gray-800/60 active:bg-gray-700/40 transition disabled:opacity-40" className="flex-1 py-3 rounded-xl text-sm font-medium text-gray-500 bg-gray-800/40 border border-gray-800/60 active:bg-gray-700/40 transition disabled:opacity-40"
> >
Cancel Cancel
</button> </button>
@@ -631,7 +631,7 @@ export default function SouqPage() {
purchasingId === showConfirmDialog.listing.id || purchasingId === showConfirmDialog.listing.id ||
user.flhBalance < showConfirmDialog.listing.priceFlh user.flhBalance < showConfirmDialog.listing.priceFlh
} }
className="flex-1 py-2.5 rounded-xl text-sm font-semibold text-[#0a0a0f] bg-[#D4AF37] active:bg-[#c5a233] transition flex items-center justify-center gap-2 disabled:opacity-60" className="flex-1 py-3 rounded-xl text-sm font-semibold text-[#0a0a0f] bg-[#D4AF37] active:bg-[#c5a233] transition flex items-center justify-center gap-2 disabled:opacity-60"
> >
{purchasingId === showConfirmDialog.listing.id ? ( {purchasingId === showConfirmDialog.listing.id ? (
<> <>
@@ -678,7 +678,7 @@ function ListingCard({
{listing.featured && ( {listing.featured && (
<div className="absolute top-2 right-2 flex items-center gap-1 bg-[#D4AF37]/20 border border-[#D4AF37]/30 rounded-full px-2 py-0.5"> <div className="absolute top-2 right-2 flex items-center gap-1 bg-[#D4AF37]/20 border border-[#D4AF37]/30 rounded-full px-2 py-0.5">
<Star size={10} className="text-[#D4AF37]" /> <Star size={10} className="text-[#D4AF37]" />
<span className="text-[8px] font-bold text-[#D4AF37]">Featured</span> <span className="text-[10px] font-bold text-[#D4AF37]">Featured</span>
</div> </div>
)} )}
</div> </div>
@@ -688,14 +688,14 @@ function ListingCard({
<h3 className="text-sm font-semibold text-white truncate mb-1"> <h3 className="text-sm font-semibold text-white truncate mb-1">
{listing.title} {listing.title}
</h3> </h3>
<p className="text-[10px] text-gray-600 line-clamp-2 mb-2 leading-relaxed"> <p className="text-xs text-gray-600 line-clamp-2 mb-2 leading-relaxed">
{listing.description} {listing.description}
</p> </p>
{/* Seller info */} {/* Seller info */}
<div className="flex items-center gap-1 mb-2"> <div className="flex items-center gap-1 mb-2">
<span className="text-[9px] text-gray-600">by</span> <span className="text-xs text-gray-600">by</span>
<span className="text-[9px] font-medium text-gray-400 truncate max-w-[80px]"> <span className="text-xs font-medium text-gray-400 truncate max-w-[80px]">
{listing.seller.name} {listing.seller.name}
</span> </span>
{listing.seller.isPro && ( {listing.seller.isPro && (
@@ -705,7 +705,7 @@ function ListingCard({
<PremiumBadge tier="premium" size="sm" /> <PremiumBadge tier="premium" size="sm" />
)} )}
{listing.seller.isPro && ( {listing.seller.isPro && (
<span className="flex items-center gap-0.5 text-[8px] text-emerald-400 font-semibold ml-0.5"> <span className="flex items-center gap-0.5 text-[10px] text-emerald-400 font-semibold ml-0.5">
<Percent size={7} /> <Percent size={7} />
0% fee 0% fee
</span> </span>
@@ -719,12 +719,12 @@ function ListingCard({
<span className="text-sm font-bold text-[#D4AF37]"> <span className="text-sm font-bold text-[#D4AF37]">
{listing.priceFlh.toLocaleString()} {listing.priceFlh.toLocaleString()}
</span> </span>
<span className="text-[8px] text-gray-600">FLH</span> <span className="text-xs text-gray-600">FLH</span>
</div> </div>
<button <button
onClick={onBuy} onClick={onBuy}
disabled={!canAfford} disabled={!canAfford}
className={`text-[10px] font-semibold px-3 py-1.5 rounded-lg transition ${ className={`text-xs font-semibold px-3 py-3 rounded-lg transition ${
canAfford canAfford
? "bg-[#D4AF37] text-[#0a0a0f] active:bg-[#c5a233]" ? "bg-[#D4AF37] text-[#0a0a0f] active:bg-[#c5a233]"
: "bg-gray-800/60 text-gray-600 cursor-not-allowed" : "bg-gray-800/60 text-gray-600 cursor-not-allowed"
+1 -1
View File
@@ -260,7 +260,7 @@ function UpgradeContent() {
<div className="text-right"> <div className="text-right">
<p className="text-xl font-bold text-white">{tier.price}</p> <p className="text-xl font-bold text-white">{tier.price}</p>
{tier.period && ( {tier.period && (
<p className="text-[11px] text-gray-500">{tier.period}</p> <p className="text-xs text-gray-500">{tier.period}</p>
)} )}
</div> </div>
</div> </div>
+9 -9
View File
@@ -215,7 +215,7 @@ export default function WalletPage() {
</div> </div>
<button <button
onClick={() => router.push("/upgrade")} onClick={() => router.push("/upgrade")}
className="mt-2 text-[11px] text-[#D4AF37] underline underline-offset-2" className="mt-2 text-xs text-[#D4AF37] underline underline-offset-2 py-1.5 px-2 -mx-2 rounded-lg"
> >
Upgrade now Upgrade now
</button> </button>
@@ -247,13 +247,13 @@ export default function WalletPage() {
<Zap size={16} className="text-[#D4AF37]" /> <Zap size={16} className="text-[#D4AF37]" />
Top Up FLH Top Up FLH
</h2> </h2>
<div className="grid grid-cols-3 gap-3"> <div className="grid grid-cols-3 gap-4">
{TOP_UP_OPTIONS.map((opt) => ( {TOP_UP_OPTIONS.map((opt) => (
<button <button
key={opt.flh} key={opt.flh}
onClick={() => handleTopUp(opt.flh)} onClick={() => handleTopUp(opt.flh)}
disabled={topupLoading === opt.flh} disabled={topupLoading === opt.flh}
className="bg-[#111118] border border-gray-800/60 rounded-2xl p-4 text-center active:scale-95 transition hover:border-[#D4AF37]/30 disabled:opacity-60" className="bg-[#111118] border border-gray-800/60 rounded-2xl p-5 text-center active:scale-95 transition hover:border-[#D4AF37]/30 disabled:opacity-60 min-h-[100px]"
> >
{topupLoading === opt.flh ? ( {topupLoading === opt.flh ? (
<Loader2 size={20} className="animate-spin mx-auto text-[#D4AF37]" /> <Loader2 size={20} className="animate-spin mx-auto text-[#D4AF37]" />
@@ -266,7 +266,7 @@ export default function WalletPage() {
${opt.usd.toFixed(2)} ${opt.usd.toFixed(2)}
</p> </p>
{opt.bonus && ( {opt.bonus && (
<p className="text-[10px] text-emerald-400 mt-1 font-medium"> <p className="text-xs text-emerald-400 mt-1 font-medium">
{opt.bonus} {opt.bonus}
</p> </p>
)} )}
@@ -295,13 +295,13 @@ export default function WalletPage() {
value={cashoutAmount} value={cashoutAmount}
onChange={(e) => setCashoutAmount(e.target.value)} onChange={(e) => setCashoutAmount(e.target.value)}
placeholder="Amount FLH" placeholder="Amount FLH"
className="w-full bg-[#1a1a24] border border-gray-800/60 rounded-xl px-4 py-3 text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/50 focus:ring-1 focus:ring-[#D4AF37]/30 transition" className="w-full bg-[#1a1a24] border border-gray-800/60 rounded-xl px-4 py-4 text-white placeholder-gray-600 focus:outline-none focus:border-[#D4AF37]/50 focus:ring-1 focus:ring-[#D4AF37]/30 transition min-h-[48px]"
/> />
</div> </div>
<button <button
type="submit" type="submit"
disabled={cashoutLoading} disabled={cashoutLoading}
className="px-5 py-3 rounded-xl bg-[#D4AF37] text-[#0a0a0f] font-semibold text-sm disabled:opacity-50 active:opacity-80 transition flex items-center gap-2" className="px-5 py-4 rounded-xl bg-[#D4AF37] text-[#0a0a0f] font-semibold text-sm disabled:opacity-50 active:opacity-80 transition flex items-center gap-2 min-h-[48px]"
> >
{cashoutLoading ? ( {cashoutLoading ? (
<Loader2 size={16} className="animate-spin" /> <Loader2 size={16} className="animate-spin" />
@@ -364,7 +364,7 @@ export default function WalletPage() {
<p className="text-sm font-medium text-white"> <p className="text-sm font-medium text-white">
{entry.amountFlh.toLocaleString()} FLH {entry.amountFlh.toLocaleString()} FLH
</p> </p>
<p className="text-[11px] text-gray-500"> <p className="text-xs text-gray-500">
${entry.fiatAmount.toFixed(2)} {" "} ${entry.fiatAmount.toFixed(2)} {" "}
{new Date(entry.createdAt).toLocaleDateString()} {new Date(entry.createdAt).toLocaleDateString()}
</p> </p>
@@ -395,8 +395,8 @@ export default function WalletPage() {
</h3> </h3>
<ul className="space-y-2"> <ul className="space-y-2">
{EARNING_TIPS.map((tip, i) => ( {EARNING_TIPS.map((tip, i) => (
<li key={i} className="flex items-start gap-2 text-sm text-gray-400"> <li key={i} className="flex items-start gap-3 text-sm text-gray-400">
<Info size={12} className="text-[#D4AF37] mt-0.5 shrink-0" /> <Info size={16} className="text-[#D4AF37] mt-0.5 shrink-0" />
<span>{tip}</span> <span>{tip}</span>
</li> </li>
))} ))}
+23 -13
View File
@@ -24,11 +24,13 @@ export default function BottomNav() {
const pathname = usePathname(); const pathname = usePathname();
return ( return (
<nav className="fixed bottom-0 left-0 right-0 z-50 bg-[#0a0a0f]/95 backdrop-blur-md border-t border-gray-800/60" <nav
style={{ paddingBottom: "env(safe-area-inset-bottom, 0px)", height: "calc(64px + env(safe-area-inset-bottom, 0px))" }}> className="fixed bottom-0 left-0 right-0 z-50 bg-[#0a0a0f]/95 backdrop-blur-md border-t border-gray-800/60 safe-area-bottom"
<div className="flex items-stretch h-16 max-w-lg mx-auto"> style={{ paddingBottom: "env(safe-area-inset-bottom, 0px)" }}
>
<div className="flex items-stretch h-14 max-w-lg mx-auto">
{navItems.map((item) => { {navItems.map((item) => {
const isActive = pathname === item.href || pathname.startsWith(item.href + "/"); const isActive = pathname === item.href || (item.href !== "/" && pathname.startsWith(item.href + "/"));
const Icon = item.icon; const Icon = item.icon;
const isHome = item.isHome; const isHome = item.isHome;
@@ -39,13 +41,15 @@ export default function BottomNav() {
href="/" href="/"
className="flex-1 flex items-center justify-center" className="flex-1 flex items-center justify-center"
> >
<div className={`w-10 h-10 rounded-full flex items-center justify-center transition-all ${ <div
className={`w-11 h-11 rounded-full flex items-center justify-center transition-all ${
pathname === "/" pathname === "/"
? "bg-[#D4AF37] text-[#0a0a0f]" ? "bg-[#D4AF37] text-[#0a0a0f] shadow-[0_0_12px_rgba(212,175,55,0.3)]"
: "bg-gray-800/60 text-gray-500" : "bg-gray-800/60 text-gray-500"
}`}> }`}
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"> >
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/> <svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
</svg> </svg>
</div> </div>
</Link> </Link>
@@ -56,19 +60,25 @@ export default function BottomNav() {
<Link <Link
key={item.href} key={item.href}
href={item.href} href={item.href}
className="flex-1 flex flex-col items-center justify-center gap-0.5 transition-opacity active:opacity-60" className="flex-1 flex flex-col items-center justify-center gap-0.5 active:opacity-60 transition-opacity relative"
> >
{Icon && ( {Icon && (
<Icon <Icon
size={20} size={22}
className={isActive ? "text-[#D4AF37]" : "text-gray-600"} className={isActive ? "text-[#D4AF37]" : "text-gray-600"}
/> />
)} )}
<span className={`text-[10px] font-medium ${ <span
className={`text-xs font-medium ${
isActive ? "text-[#D4AF37]" : "text-gray-600" isActive ? "text-[#D4AF37]" : "text-gray-600"
}`}> }`}
>
{item.label} {item.label}
</span> </span>
{/* Active indicator */}
{isActive && (
<div className="absolute -top-0.5 left-1/2 -translate-x-1/2 w-5 h-0.5 rounded-full bg-[#D4AF37]" />
)}
</Link> </Link>
); );
})} })}
+1 -1
View File
@@ -205,7 +205,7 @@ export default function NotificationPanel({
> >
{notif.title} {notif.title}
</p> </p>
<span className="text-[10px] text-gray-500 whitespace-nowrap mt-0.5"> <span className="text-xs text-gray-500 whitespace-nowrap mt-0.5">
{timeAgo(notif.createdAt)} {timeAgo(notif.createdAt)}
</span> </span>
</div> </div>
+2 -2
View File
@@ -9,8 +9,8 @@ interface PremiumBadgeProps {
export default function PremiumBadge({ tier, size = "sm" }: PremiumBadgeProps) { export default function PremiumBadge({ tier, size = "sm" }: PremiumBadgeProps) {
const sizeMap = { const sizeMap = {
sm: { px: "px-1.5 py-0.5", text: "text-[9px]", icon: 8, gap: "gap-0.5" }, sm: { px: "px-1.5 py-0.5", text: "text-[10px]", icon: 8, gap: "gap-0.5" },
md: { px: "px-2 py-0.5", text: "text-[10px]", icon: 10, gap: "gap-1" }, md: { px: "px-2 py-0.5", text: "text-xs", icon: 10, gap: "gap-1" },
lg: { px: "px-2.5 py-1", text: "text-xs", icon: 12, gap: "gap-1" }, lg: { px: "px-2.5 py-1", text: "text-xs", icon: 12, gap: "gap-1" },
}; };