@@ -31,59 +18,28 @@ export default function UsersPage() {
title="Users"
description="Manage team members and their roles"
>
- {user?.role === "super_admin" && (
-
-
-
-
-
-
-
-
{users.length}
-
Total Users
+ {stats.map((s) => (
+
+
+
+
+
+
+
{s.value}
+
{s.label}
+
-
-
-
-
-
-
-
-
{users.filter((u) => u.active).length}
-
Active
-
-
-
-
-
-
-
-
-
-
{users.filter((u) => u.role === "admin").length}
-
Admins
-
-
-
-
-
-
-
-
-
-
{users.filter((u) => u.role === "sales").length}
-
Sales
-
-
-
+ ))}
@@ -97,10 +53,14 @@ export default function UsersPage() {
-
+
-
+
- )
+ );
}
diff --git a/src/app/globals.css b/src/app/globals.css
index 5fe372e..5615ace 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -2,77 +2,73 @@
@tailwind components;
@tailwind utilities;
-@layer base {
- :root {
- --background: 210 40% 98%;
- --foreground: 222.2 84% 4.9%;
- --card: 0 0% 100%;
- --card-foreground: 222.2 84% 4.9%;
- --popover: 0 0% 100%;
- --popover-foreground: 222.2 84% 4.9%;
- --primary: 221.2 83.2% 53.3%;
- --primary-foreground: 210 40% 98%;
- --secondary: 210 40% 96.1%;
- --secondary-foreground: 222.2 47.4% 11.2%;
- --muted: 210 40% 96.1%;
- --muted-foreground: 215.4 16.3% 46.9%;
- --accent: 210 40% 96.1%;
- --accent-foreground: 222.2 47.4% 11.2%;
- --destructive: 0 84.2% 60.2%;
- --destructive-foreground: 210 40% 98%;
- --border: 214.3 31.8% 91.4%;
- --input: 214.3 31.8% 91.4%;
- --ring: 221.2 83.2% 53.3%;
- --sidebar: 222.2 84% 4.9%;
- --sidebar-foreground: 210 40% 98%;
- --sidebar-primary: 217.2 91.2% 59.8%;
- --sidebar-primary-foreground: 0 0% 100%;
- --sidebar-accent: 217.2 32.6% 17.5%;
- --sidebar-accent-foreground: 210 40% 98%;
- --sidebar-border: 217.2 32.6% 17.5%;
- --sidebar-ring: 224.3 76.3% 48%;
- --radius: 0.5rem;
- }
+:root {
+ --background: 210 40% 98%;
+ --foreground: 222.2 84% 4.9%;
+ --card: 0 0% 100%;
+ --card-foreground: 222.2 84% 4.9%;
+ --popover: 0 0% 100%;
+ --popover-foreground: 222.2 84% 4.9%;
+ --primary: 221.2 83.2% 53.3%;
+ --primary-foreground: 210 40% 98%;
+ --secondary: 210 40% 96.1%;
+ --secondary-foreground: 222.2 47.4% 11.2%;
+ --muted: 210 40% 96.1%;
+ --muted-foreground: 215.4 16.3% 46.9%;
+ --accent: 210 40% 96.1%;
+ --accent-foreground: 222.2 47.4% 11.2%;
+ --destructive: 0 84.2% 60.2%;
+ --destructive-foreground: 210 40% 98%;
+ --border: 214.3 31.8% 91.4%;
+ --input: 214.3 31.8% 91.4%;
+ --ring: 221.2 83.2% 53.3%;
+ --sidebar: 222.2 84% 4.9%;
+ --sidebar-foreground: 210 40% 98%;
+ --sidebar-primary: 217.2 91.2% 59.8%;
+ --sidebar-primary-foreground: 0 0% 100%;
+ --sidebar-accent: 217.2 32.6% 17.5%;
+ --sidebar-accent-foreground: 210 40% 98%;
+ --sidebar-border: 217.2 32.6% 17.5%;
+ --sidebar-ring: 224.3 76.3% 48%;
+ --radius: 0.5rem;
+}
- .dark {
- --background: 222.2 84% 4.9%;
- --foreground: 210 40% 98%;
- --card: 222.2 84% 4.9%;
- --card-foreground: 210 40% 98%;
- --popover: 222.2 84% 4.9%;
- --popover-foreground: 210 40% 98%;
- --primary: 217.2 91.2% 59.8%;
- --primary-foreground: 222.2 47.4% 11.2%;
- --secondary: 217.2 32.6% 17.5%;
- --secondary-foreground: 210 40% 98%;
- --muted: 217.2 32.6% 17.5%;
- --muted-foreground: 215 20.2% 65.1%;
- --accent: 217.2 32.6% 17.5%;
- --accent-foreground: 210 40% 98%;
- --destructive: 0 62.8% 30.6%;
- --destructive-foreground: 210 40% 98%;
- --border: 217.2 32.6% 17.5%;
- --input: 217.2 32.6% 17.5%;
- --ring: 224.3 76.3% 48%;
- --sidebar: 222.2 84% 4.9%;
- --sidebar-foreground: 210 40% 98%;
- --sidebar-primary: 217.2 91.2% 59.8%;
- --sidebar-primary-foreground: 0 0% 100%;
- --sidebar-accent: 217.2 32.6% 17.5%;
- --sidebar-accent-foreground: 210 40% 98%;
- --sidebar-border: 217.2 32.6% 17.5%;
- --sidebar-ring: 224.3 76.3% 48%;
- }
+.dark {
+ --background: 222.2 84% 4.9%;
+ --foreground: 210 40% 98%;
+ --card: 222.2 84% 4.9%;
+ --card-foreground: 210 40% 98%;
+ --popover: 222.2 84% 4.9%;
+ --popover-foreground: 210 40% 98%;
+ --primary: 217.2 91.2% 59.8%;
+ --primary-foreground: 222.2 47.4% 11.2%;
+ --secondary: 217.2 32.6% 17.5%;
+ --secondary-foreground: 210 40% 98%;
+ --muted: 217.2 32.6% 17.5%;
+ --muted-foreground: 215 20.2% 65.1%;
+ --accent: 217.2 32.6% 17.5%;
+ --accent-foreground: 210 40% 98%;
+ --destructive: 0 62.8% 30.6%;
+ --destructive-foreground: 210 40% 98%;
+ --border: 217.2 32.6% 17.5%;
+ --input: 217.2 32.6% 17.5%;
+ --ring: 224.3 76.3% 48%;
+ --sidebar: 222.2 84% 4.9%;
+ --sidebar-foreground: 210 40% 98%;
+ --sidebar-primary: 217.2 91.2% 59.8%;
+ --sidebar-primary-foreground: 0 0% 100%;
+ --sidebar-accent: 217.2 32.6% 17.5%;
+ --sidebar-accent-foreground: 210 40% 98%;
+ --sidebar-border: 217.2 32.6% 17.5%;
+ --sidebar-ring: 224.3 76.3% 48%;
+}
* {
@apply border-border;
}
-
-
body {
@apply bg-background text-foreground;
font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;
}
-
}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
new file mode 100644
index 0000000..b333a78
--- /dev/null
+++ b/src/app/layout.tsx
@@ -0,0 +1,35 @@
+import type { Metadata } from "next"
+import { Inter } from "next/font/google"
+import { ThemeProvider } from "@/providers/theme-provider"
+import { Toaster } from "@/components/ui/sonner"
+import "./globals.css"
+
+const inter = Inter({
+ variable: "--font-inter",
+ subsets: ["latin"],
+})
+
+export const metadata: Metadata = {
+ title: "Coast IT - CRM",
+ description: "Customer Relationship Management System",
+ icons: {
+ icon: "/logo/CompanyMiniLogo.png",
+ },
+}
+
+export default function RootLayout({
+ children,
+}: Readonly<{
+ children: React.ReactNode
+}>) {
+ return (
+
+
+
+ {children}
+
+
+
+
+ )
+}
diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx
index 2375af0..c8a58fc 100644
--- a/src/app/login/page.tsx
+++ b/src/app/login/page.tsx
@@ -1,13 +1,14 @@
"use client"
-import { Suspense, useState } from "react"
-import { useRouter, useSearchParams } from "next/navigation"
+import { useState } from "react"
+import { useRouter } from "next/navigation"
import { motion } from "framer-motion"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
+import { Checkbox } from "@/components/ui/checkbox"
import { COMPANY_NAME } from "@/lib/constants"
-import { Eye, EyeOff, Loader2, AlertCircle } from "lucide-react"
+import { Eye, EyeOff, Loader2 } from "lucide-react"
function LoginForm() {
const router = useRouter()
@@ -16,191 +17,409 @@ function LoginForm() {
const [password, setPassword] = useState("")
const [showPassword, setShowPassword] = useState(false)
const [loading, setLoading] = useState(false)
- const [error, setError] = useState("")
+ const [remember, setRemember] = useState(false)
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setError("")
setLoading(true)
- try {
- const res = await fetch("/api/auth/login", {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ email, password }),
- })
+ await new Promise((resolve) => setTimeout(resolve, 1200))
- const data = await res.json()
-
- if (!res.ok) {
- setError(data.error || "Authentication failed.")
- setLoading(false)
- return
- }
-
- const redirect = searchParams.get("redirect") || "/dashboard"
- router.push(redirect)
- } catch {
- setError("Unable to connect to authentication service. Please ensure the database is running.")
- setLoading(false)
- }
+ router.push("/dashboard")
}
return (
<>
- {error && (
-
- )}
+
-