Skip to content

Commit a607f39

Browse files
committed
visual fixes
1 parent e05db90 commit a607f39

File tree

9 files changed

+146
-20
lines changed

9 files changed

+146
-20
lines changed

web-next/app/(app)/dashboard/page.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
22
import { getAllStudents } from "@/lib/repositories/students";
33
import { getRecentTransactions, getStudentIdsWithTransactions, getWeeklyTopupData, getTotalSalesCount } from "@/lib/repositories/transactions";
4-
import { Users, ShoppingCart, AlertTriangle, DollarSign, ArrowUpRight, ArrowDownRight } from "lucide-react";
4+
import { Users, ShoppingCart, AlertTriangle, DollarSign, ArrowUpRight, ArrowDownRight, Minus } from "lucide-react";
55
import { WeeklyTopupChart } from "@/components/weekly-topup-chart";
66
import { formatCurrency } from "@/lib/currency";
77
import { Metadata } from 'next';
@@ -117,9 +117,13 @@ export default async function DashboardPage() {
117117
? "bg-green-100 dark:bg-green-900/20"
118118
: tx.type === "DEBIT"
119119
? "bg-red-100 dark:bg-red-900/20"
120+
: tx.type === "ADJUST"
121+
? "bg-gray-100 dark:bg-gray-800/40"
120122
: "bg-gray-100 dark:bg-gray-900/20"
121123
}`}>
122-
{tx.amount >= 0 ? (
124+
{tx.type === "ADJUST" ? (
125+
<Minus className="h-4 w-4 text-gray-600 dark:text-gray-400" />
126+
) : tx.amount >= 0 ? (
123127
<ArrowUpRight className={`h-4 w-4 ${
124128
tx.type === "TOPUP" ? "text-green-600" : "text-gray-600"
125129
}`} />
@@ -139,7 +143,11 @@ export default async function DashboardPage() {
139143
<div className="text-right space-y-1 flex-shrink-0">
140144
<p
141145
className={`text-sm font-medium whitespace-nowrap ${
142-
tx.amount >= 0 ? "text-green-600" : "text-red-600"
146+
tx.type === "ADJUST"
147+
? "text-gray-600 dark:text-gray-400"
148+
: tx.amount >= 0
149+
? "text-green-600"
150+
: "text-red-600"
143151
}`}
144152
>
145153
{tx.amount >= 0 ? "+" : ""}¥{formatCurrency(Math.abs(tx.amount))}

web-next/app/(app)/pos/pos-form.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -336,13 +336,6 @@ export function PosForm({ students, studentIdsWithTransactions, userName }: PosF
336336
</div>
337337
</div>
338338
<DialogFooter className="flex-col sm:flex-col gap-2">
339-
<Button
340-
onClick={() => handleEnrollCard('checkout')}
341-
disabled={enrollLoading || !enrollName}
342-
className="w-full"
343-
>
344-
{enrollLoading ? "Enrolling..." : "Enroll & Process Payment"}
345-
</Button>
346339
<Button
347340
variant="secondary"
348341
onClick={() => handleEnrollCard('topup')}

web-next/app/(auth)/signup/page.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { useState } from "react";
44
import Link from "next/link";
55
import { useRouter } from "next/navigation";
66
import { authClient } from "@/lib/auth-client";
7+
import { verifySignupCode } from "@/app/actions/users";
78
import { Button } from "@/components/ui/button";
89
import {
910
Card,
@@ -27,8 +28,6 @@ import {
2728
} from "@/components/ui/tooltip";
2829
import { toast } from "sonner";
2930

30-
const SIGNUP_CODE = "uGFk@j3A";
31-
3231
export default function SignupPage() {
3332
const router = useRouter();
3433
const [loading, setLoading] = useState(false);
@@ -51,14 +50,18 @@ export default function SignupPage() {
5150

5251
// Auto-verify when all 8 digits are entered
5352
if (value.length === 8) {
54-
if (value !== SIGNUP_CODE) {
55-
toast.error("Invalid code. Please try again.");
53+
setLoading(true);
54+
55+
// Verify the code on the server
56+
const verificationResult = await verifySignupCode(value);
57+
58+
if (!verificationResult.success) {
59+
toast.error(verificationResult.error || "Invalid code. Please try again.");
5660
setOtp("");
61+
setLoading(false);
5762
return;
5863
}
5964

60-
setLoading(true);
61-
6265
try {
6366
const { data, error } = await authClient.signUp.email({
6467
email: formData.email,

web-next/app/actions/users.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,25 @@ import {
88
} from "@/lib/models";
99
import { revalidatePath } from "next/cache";
1010

11+
/**
12+
* Verify signup code
13+
* The code is stored securely in environment variables and never exposed to the client
14+
*/
15+
export async function verifySignupCode(code: string) {
16+
const validCode = process.env.SIGNUP_CODE;
17+
18+
if (!validCode) {
19+
console.error("SIGNUP_CODE environment variable is not set");
20+
return { success: false, error: "Signup verification is not configured" };
21+
}
22+
23+
if (code === validCode) {
24+
return { success: true };
25+
}
26+
27+
return { success: false, error: "Invalid signup code" };
28+
}
29+
1130
export async function getCurrentUser() {
1231
try {
1332
const db = getDb();

web-next/app/globals.css

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
--color-input: var(--input);
2626
--color-border: var(--border);
2727
--color-destructive: var(--destructive);
28+
--color-destructive-foreground: var(--destructive-foreground);
2829
--color-accent-foreground: var(--accent-foreground);
2930
--color-accent: var(--accent);
3031
--color-muted-foreground: var(--muted-foreground);
@@ -45,6 +46,8 @@
4546

4647
:root {
4748
--radius: 0.625rem;
49+
50+
/* Light mode colors */
4851
--background: oklch(1 0 0);
4952
--foreground: oklch(0.145 0 0);
5053
--card: oklch(1 0 0);
@@ -60,6 +63,7 @@
6063
--accent: oklch(0.97 0 0);
6164
--accent-foreground: oklch(0.205 0 0);
6265
--destructive: oklch(0.577 0.245 27.325);
66+
--destructive-foreground: oklch(0.985 0 0);
6367
--border: oklch(0.922 0 0);
6468
--input: oklch(0.922 0 0);
6569
--ring: oklch(0.708 0 0);
@@ -78,7 +82,84 @@
7882
--sidebar-ring: oklch(0.708 0 0);
7983
}
8084

81-
.dark {
85+
/* Apply dark colors by default if system prefers dark AND no explicit theme is set */
86+
@media (prefers-color-scheme: dark) {
87+
html:not(.light):not(.dark) {
88+
--background: oklch(0.145 0 0);
89+
--foreground: oklch(0.985 0 0);
90+
--card: oklch(0.205 0 0);
91+
--card-foreground: oklch(0.985 0 0);
92+
--popover: oklch(0.205 0 0);
93+
--popover-foreground: oklch(0.985 0 0);
94+
--primary: oklch(0.922 0 0);
95+
--primary-foreground: oklch(0.205 0 0);
96+
--secondary: oklch(0.269 0 0);
97+
--secondary-foreground: oklch(0.985 0 0);
98+
--muted: oklch(0.269 0 0);
99+
--muted-foreground: oklch(0.708 0 0);
100+
--accent: oklch(0.269 0 0);
101+
--accent-foreground: oklch(0.985 0 0);
102+
--destructive: oklch(0.704 0.191 22.216);
103+
--destructive-foreground: oklch(0.985 0 0);
104+
--border: oklch(1 0 0 / 10%);
105+
--input: oklch(1 0 0 / 15%);
106+
--ring: oklch(0.556 0 0);
107+
--chart-1: oklch(0.488 0.243 264.376);
108+
--chart-2: oklch(0.696 0.17 162.48);
109+
--chart-3: oklch(0.769 0.188 70.08);
110+
--chart-4: oklch(0.627 0.265 303.9);
111+
--chart-5: oklch(0.645 0.246 16.439);
112+
--sidebar: oklch(0.205 0 0);
113+
--sidebar-foreground: oklch(0.985 0 0);
114+
--sidebar-primary: oklch(0.488 0.243 264.376);
115+
--sidebar-primary-foreground: oklch(0.985 0 0);
116+
--sidebar-accent: oklch(0.269 0 0);
117+
--sidebar-accent-foreground: oklch(0.985 0 0);
118+
--sidebar-border: oklch(1 0 0 / 10%);
119+
--sidebar-ring: oklch(0.556 0 0);
120+
}
121+
}
122+
123+
/* Explicit light mode - overrides system preference */
124+
html.light,
125+
:root.light {
126+
--background: oklch(1 0 0);
127+
--foreground: oklch(0.145 0 0);
128+
--card: oklch(1 0 0);
129+
--card-foreground: oklch(0.145 0 0);
130+
--popover: oklch(1 0 0);
131+
--popover-foreground: oklch(0.145 0 0);
132+
--primary: oklch(0.205 0 0);
133+
--primary-foreground: oklch(0.985 0 0);
134+
--secondary: oklch(0.97 0 0);
135+
--secondary-foreground: oklch(0.205 0 0);
136+
--muted: oklch(0.97 0 0);
137+
--muted-foreground: oklch(0.556 0 0);
138+
--accent: oklch(0.97 0 0);
139+
--accent-foreground: oklch(0.205 0 0);
140+
--destructive: oklch(0.577 0.245 27.325);
141+
--destructive-foreground: oklch(0.985 0 0);
142+
--border: oklch(0.922 0 0);
143+
--input: oklch(0.922 0 0);
144+
--ring: oklch(0.708 0 0);
145+
--chart-1: oklch(0.646 0.222 41.116);
146+
--chart-2: oklch(0.6 0.118 184.704);
147+
--chart-3: oklch(0.398 0.07 227.392);
148+
--chart-4: oklch(0.828 0.189 84.429);
149+
--chart-5: oklch(0.769 0.188 70.08);
150+
--sidebar: oklch(0.985 0 0);
151+
--sidebar-foreground: oklch(0.145 0 0);
152+
--sidebar-primary: oklch(0.205 0 0);
153+
--sidebar-primary-foreground: oklch(0.985 0 0);
154+
--sidebar-accent: oklch(0.97 0 0);
155+
--sidebar-accent-foreground: oklch(0.205 0 0);
156+
--sidebar-border: oklch(0.922 0 0);
157+
--sidebar-ring: oklch(0.708 0 0);
158+
}
159+
160+
/* Explicit dark mode */
161+
html.dark,
162+
:root.dark {
82163
--background: oklch(0.145 0 0);
83164
--foreground: oklch(0.985 0 0);
84165
--card: oklch(0.205 0 0);
@@ -94,6 +175,7 @@
94175
--accent: oklch(0.269 0 0);
95176
--accent-foreground: oklch(0.985 0 0);
96177
--destructive: oklch(0.704 0.191 22.216);
178+
--destructive-foreground: oklch(0.985 0 0);
97179
--border: oklch(1 0 0 / 10%);
98180
--input: oklch(1 0 0 / 15%);
99181
--ring: oklch(0.556 0 0);
@@ -113,9 +195,15 @@
113195
}
114196

115197
@layer base {
198+
/* Prevent transitions on theme changes to avoid flash */
199+
html, body {
200+
transition: none !important;
201+
}
202+
116203
* {
117204
@apply border-border outline-ring/50;
118205
}
206+
119207
body {
120208
@apply bg-background text-foreground;
121209
}

web-next/app/layout.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ export default function RootLayout({
4949
}>) {
5050
return (
5151
<html lang="en" suppressHydrationWarning>
52+
<head>
53+
<script
54+
dangerouslySetInnerHTML={{
55+
__html: `(function(){try{let t=localStorage.getItem('theme'),d=window.matchMedia('(prefers-color-scheme: dark)').matches;if(t==='dark'||(t!=='light'&&!t&&d)){document.documentElement.classList.add('dark');document.documentElement.classList.remove('light')}else if(t==='light'){document.documentElement.classList.add('light');document.documentElement.classList.remove('dark')}else{document.documentElement.classList.remove('dark','light')}}catch(e){}})()`,
56+
}}
57+
/>
58+
</head>
5259
<body
5360
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
5461
>
@@ -57,6 +64,7 @@ export default function RootLayout({
5764
defaultTheme="system"
5865
enableSystem
5966
disableTransitionOnChange
67+
storageKey="theme"
6068
>
6169
{children}
6270
<Toaster />

web-next/components/theme-provider.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ export function ThemeProvider({
77
children,
88
...props
99
}: React.ComponentProps<typeof NextThemesProvider>) {
10-
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
10+
return (
11+
<NextThemesProvider
12+
{...props}
13+
enableColorScheme={false}
14+
>
15+
{children}
16+
</NextThemesProvider>
17+
)
1118
}
1219

web-next/components/ui/badge.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const badgeVariants = cva(
1414
secondary:
1515
"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
1616
destructive:
17-
"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
17+
"border-transparent bg-destructive text-destructive-foreground [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
1818
outline:
1919
"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
2020
},

web-next/components/ui/button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const buttonVariants = cva(
1111
variant: {
1212
default: "bg-primary text-primary-foreground hover:bg-primary/90",
1313
destructive:
14-
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
14+
"bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
1515
outline:
1616
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
1717
secondary:

0 commit comments

Comments
 (0)