light and dark mode fixed and default mode is the default unless you pick Spidey mode
Build & Auto-Repair / build (push) Has been cancelled
Build & Auto-Repair / build (push) Has been cancelled
This commit is contained in:
@@ -4,6 +4,37 @@
|
|||||||
============================================================================ */
|
============================================================================ */
|
||||||
|
|
||||||
.theme-spidey {
|
.theme-spidey {
|
||||||
|
--background: 240 18% 97%;
|
||||||
|
--foreground: 240 8% 14%;
|
||||||
|
--card: 0 0% 100%;
|
||||||
|
--card-foreground: 240 8% 14%;
|
||||||
|
--popover: 0 0% 100%;
|
||||||
|
--popover-foreground: 240 8% 14%;
|
||||||
|
--primary: 0 90% 46%;
|
||||||
|
--primary-foreground: 0 0% 100%;
|
||||||
|
--secondary: 220 75% 48%;
|
||||||
|
--secondary-foreground: 0 0% 100%;
|
||||||
|
--muted: 240 8% 92%;
|
||||||
|
--muted-foreground: 240 5% 50%;
|
||||||
|
--accent: 220 15% 90%;
|
||||||
|
--accent-foreground: 220 60% 28%;
|
||||||
|
--destructive: 0 70% 46%;
|
||||||
|
--destructive-foreground: 0 0% 100%;
|
||||||
|
--border: 240 8% 84%;
|
||||||
|
--input: 240 8% 84%;
|
||||||
|
--ring: 0 90% 46%;
|
||||||
|
--radius: 0.5rem;
|
||||||
|
--sidebar: 0 0% 99%;
|
||||||
|
--sidebar-foreground: 240 8% 14%;
|
||||||
|
--sidebar-primary: 0 90% 46%;
|
||||||
|
--sidebar-primary-foreground: 0 0% 100%;
|
||||||
|
--sidebar-accent: 220 20% 93%;
|
||||||
|
--sidebar-accent-foreground: 220 70% 28%;
|
||||||
|
--sidebar-border: 240 8% 84%;
|
||||||
|
--sidebar-ring: 0 90% 46%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark.theme-spidey {
|
||||||
--background: 222.2 84% 4.9%;
|
--background: 222.2 84% 4.9%;
|
||||||
--foreground: 210 40% 98%;
|
--foreground: 210 40% 98%;
|
||||||
--card: 222.2 84% 4.9%;
|
--card: 222.2 84% 4.9%;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
setSessionContext,
|
setSessionContext,
|
||||||
SESSION_COOKIE,
|
SESSION_COOKIE,
|
||||||
} from "@/lib/auth"
|
} from "@/lib/auth"
|
||||||
|
import { query } from "@/lib/db"
|
||||||
|
|
||||||
function jsonResponse(data: unknown, status: number) {
|
function jsonResponse(data: unknown, status: number) {
|
||||||
return new Response(JSON.stringify(data), {
|
return new Response(JSON.stringify(data), {
|
||||||
@@ -114,6 +115,11 @@ export async function POST(request: NextRequest) {
|
|||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await query(
|
||||||
|
`UPDATE users SET preferences = preferences || $2::jsonb WHERE id = $1`,
|
||||||
|
[dbUser.id, JSON.stringify({ website_theme: "default" })],
|
||||||
|
)
|
||||||
|
|
||||||
const token = await createSession(dbUser.id, dbUser.role_name)
|
const token = await createSession(dbUser.id, dbUser.role_name)
|
||||||
await setSessionContext(dbUser.id, ipAddress)
|
await setSessionContext(dbUser.id, ipAddress)
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { useState, useEffect, useRef, Suspense } from "react"
|
|||||||
import { useSearchParams, useRouter } from "next/navigation"
|
import { useSearchParams, useRouter } from "next/navigation"
|
||||||
import { Eye, EyeOff, Loader2 } from "lucide-react"
|
import { Eye, EyeOff, Loader2 } from "lucide-react"
|
||||||
|
|
||||||
|
const WEBSITE_THEME_KEY = "crm-website-theme"
|
||||||
|
|
||||||
const waves = [
|
const waves = [
|
||||||
{ a: 16, f: 0.011, s: 0.018, y: 0.38, fill: "rgba(27,176,206,0.18)" },
|
{ a: 16, f: 0.011, s: 0.018, y: 0.38, fill: "rgba(27,176,206,0.18)" },
|
||||||
{ a: 20, f: 0.008, s: 0.013, y: 0.52, fill: "rgba(27,176,206,0.25)" },
|
{ a: 20, f: 0.008, s: 0.013, y: 0.52, fill: "rgba(27,176,206,0.25)" },
|
||||||
@@ -227,6 +229,9 @@ function LoginForm() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
localStorage.removeItem(WEBSITE_THEME_KEY)
|
||||||
|
const root = document.documentElement
|
||||||
|
root.className = root.className.split(" ").filter((c) => !c.startsWith("theme-")).join(" ").trim()
|
||||||
const redirectTo = searchParams.get("redirect") || "/dashboard"
|
const redirectTo = searchParams.get("redirect") || "/dashboard"
|
||||||
router.push(redirectTo)
|
router.push(redirectTo)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ function getStoredColorTheme(): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function applyColorTheme(theme: string) {
|
function applyColorTheme(theme: string) {
|
||||||
document.documentElement.className = document.documentElement.className
|
const colorThemes = ["default","ocean","forest","sunset","midnight","rose","amber","violet","slate","ruby"]
|
||||||
.replace(/\b(default|ocean|forest|sunset|midnight|rose|amber|violet|slate|ruby)\b/g, "")
|
const classes = document.documentElement.className.split(" ").filter(c => !colorThemes.includes(c))
|
||||||
.trim()
|
|
||||||
if (theme !== "default") {
|
if (theme !== "default") {
|
||||||
document.documentElement.classList.add(theme)
|
classes.push(theme)
|
||||||
}
|
}
|
||||||
|
document.documentElement.className = classes.join(" ").trim()
|
||||||
localStorage.setItem(COLOR_THEME_KEY, theme)
|
localStorage.setItem(COLOR_THEME_KEY, theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { createContext, useContext, useState, useEffect, ReactNode, useCallback
|
|||||||
const WEBSITE_THEME_KEY = "crm-website-theme"
|
const WEBSITE_THEME_KEY = "crm-website-theme"
|
||||||
|
|
||||||
const themeClasses: Record<string, string> = {
|
const themeClasses: Record<string, string> = {
|
||||||
default: "theme-default",
|
|
||||||
spidey: "theme-spidey",
|
spidey: "theme-spidey",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,13 +42,6 @@ export function WebsiteThemeProvider({ children }: { children: ReactNode }) {
|
|||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const stored = getStoredTheme()
|
|
||||||
if (stored) {
|
|
||||||
setWebsiteThemeState(stored)
|
|
||||||
applyWebsiteTheme(stored)
|
|
||||||
setLoading(false)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fetch("/api/settings/website-theme")
|
fetch("/api/settings/website-theme")
|
||||||
.then((res) => (res.ok ? res.json() : null))
|
.then((res) => (res.ok ? res.json() : null))
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
@@ -59,7 +51,10 @@ export function WebsiteThemeProvider({ children }: { children: ReactNode }) {
|
|||||||
applyWebsiteTheme(theme)
|
applyWebsiteTheme(theme)
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
applyWebsiteTheme("default")
|
const stored = getStoredTheme()
|
||||||
|
const theme = stored || "default"
|
||||||
|
setWebsiteThemeState(theme)
|
||||||
|
applyWebsiteTheme(theme)
|
||||||
})
|
})
|
||||||
.finally(() => setLoading(false))
|
.finally(() => setLoading(false))
|
||||||
}, [])
|
}, [])
|
||||||
|
|||||||
Reference in New Issue
Block a user