Theme select & Accessability :^)
All checks were successful
Docker Deploy / build-and-push (push) Successful in 4m0s
All checks were successful
Docker Deploy / build-and-push (push) Successful in 4m0s
This commit is contained in:
@@ -11,7 +11,7 @@ export default defineConfig({
|
||||
output: "server",
|
||||
integrations: [vue(), icon()],
|
||||
security: {
|
||||
csp: true,
|
||||
csp: process.env.NODE_ENV === "production",
|
||||
},
|
||||
vite: {
|
||||
plugins: [tailwindcss()],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "chronus",
|
||||
"type": "module",
|
||||
"version": "2.2.1",
|
||||
"version": "2.3.0",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"build": "astro build",
|
||||
@@ -12,7 +12,7 @@
|
||||
"migrate": "node scripts/migrate.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/check": "0.9.6-beta.1",
|
||||
"@astrojs/check": "0.9.6",
|
||||
"@astrojs/node": "10.0.0-beta.0",
|
||||
"@astrojs/vue": "6.0.0-beta.0",
|
||||
"@ceereals/vue-pdf": "^0.2.1",
|
||||
|
||||
459
pnpm-lock.yaml
generated
459
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
34
src/components/ThemeToggle.vue
Normal file
34
src/components/ThemeToggle.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { Icon } from '@iconify/vue';
|
||||
|
||||
const theme = ref('macchiato');
|
||||
|
||||
onMounted(() => {
|
||||
const stored = localStorage.getItem('theme');
|
||||
if (stored) {
|
||||
theme.value = stored;
|
||||
document.documentElement.setAttribute('data-theme', stored);
|
||||
}
|
||||
});
|
||||
|
||||
function toggleTheme() {
|
||||
const newTheme = theme.value === 'macchiato' ? 'latte' : 'macchiato';
|
||||
theme.value = newTheme;
|
||||
document.documentElement.setAttribute('data-theme', newTheme);
|
||||
localStorage.setItem('theme', newTheme);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
@click="toggleTheme"
|
||||
class="btn btn-ghost btn-circle"
|
||||
aria-label="Toggle Theme"
|
||||
>
|
||||
<Icon
|
||||
:icon="theme === 'macchiato' ? 'heroicons:moon' : 'heroicons:sun'"
|
||||
class="w-5 h-5"
|
||||
/>
|
||||
</button>
|
||||
</template>
|
||||
@@ -5,6 +5,7 @@ import { db } from '../db';
|
||||
import { members, organizations } from '../db/schema';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import Avatar from '../components/Avatar.astro';
|
||||
import ThemeToggle from '../components/ThemeToggle.vue';
|
||||
import { ClientRouter } from "astro:transitions";
|
||||
|
||||
interface Props {
|
||||
@@ -32,7 +33,7 @@ const currentTeam = userMemberships.find(m => m.organization.id === currentTeamI
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en" data-theme="dark">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="Chronus Dashboard" />
|
||||
@@ -41,6 +42,10 @@ const currentTeam = userMemberships.find(m => m.organization.id === currentTeamI
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{title}</title>
|
||||
<ClientRouter />
|
||||
<script is:inline>
|
||||
const theme = localStorage.getItem('theme') || 'macchiato';
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
</script>
|
||||
</head>
|
||||
<body class="bg-base-100 h-screen flex flex-col overflow-hidden">
|
||||
<div class="drawer lg:drawer-open flex-1 overflow-auto">
|
||||
@@ -57,6 +62,9 @@ const currentTeam = userMemberships.find(m => m.organization.id === currentTeamI
|
||||
<img src="/logo.webp" alt="Chronus" class="h-8 w-8" />
|
||||
<span class="text-xl font-bold text-primary">Chronus</span>
|
||||
</div>
|
||||
<div class="flex-none">
|
||||
<ThemeToggle client:load />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Page content here -->
|
||||
@@ -177,6 +185,13 @@ const currentTeam = userMemberships.find(m => m.organization.id === currentTeamI
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="flex justify-between items-center p-2 hover:bg-transparent">
|
||||
<span class="font-semibold text-sm text-base-content/70 pl-2">Theme</span>
|
||||
<ThemeToggle client:load />
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<form action="/api/auth/logout" method="POST" class="contents">
|
||||
<button type="submit" class="flex w-full items-center gap-2 py-2 px-4 text-error hover:bg-error/10 rounded-lg transition-colors active:bg-base-300/50!">
|
||||
|
||||
@@ -10,7 +10,7 @@ const { title } = Astro.props;
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en" data-theme="dark">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="Chronus Time Tracking" />
|
||||
@@ -19,6 +19,10 @@ const { title } = Astro.props;
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{title}</title>
|
||||
<ClientRouter />
|
||||
<script is:inline>
|
||||
const theme = localStorage.getItem('theme') || 'macchiato';
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
</script>
|
||||
</head>
|
||||
<body class="min-h-screen bg-base-100 text-base-content flex flex-col">
|
||||
<div class="flex-1 flex flex-col">
|
||||
|
||||
@@ -42,6 +42,7 @@ const errorMessage =
|
||||
name="email"
|
||||
placeholder="your@email.com"
|
||||
class="input input-bordered w-full"
|
||||
autocomplete="email"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
@@ -56,6 +57,7 @@ const errorMessage =
|
||||
name="password"
|
||||
placeholder="Enter your password"
|
||||
class="input input-bordered w-full"
|
||||
autocomplete="current-password"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -74,6 +74,7 @@ const errorMessage =
|
||||
name="name"
|
||||
placeholder="John Doe"
|
||||
class="input input-bordered w-full"
|
||||
autocomplete="name"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
@@ -88,6 +89,7 @@ const errorMessage =
|
||||
name="email"
|
||||
placeholder="your@email.com"
|
||||
class="input input-bordered w-full"
|
||||
autocomplete="email"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
@@ -102,6 +104,7 @@ const errorMessage =
|
||||
name="password"
|
||||
placeholder="Create a strong password"
|
||||
class="input input-bordered w-full"
|
||||
autocomplete="new-password"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -2,4 +2,5 @@
|
||||
@plugin "daisyui" {
|
||||
themes: false;
|
||||
}
|
||||
@plugin "./theme.ts";
|
||||
@plugin "./theme-dark.ts";
|
||||
@plugin "./theme-light.ts";
|
||||
|
||||
9
src/styles/theme-light.ts
Normal file
9
src/styles/theme-light.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { createCatppuccinPlugin } from "@catppuccin/daisyui";
|
||||
|
||||
export default createCatppuccinPlugin(
|
||||
"latte",
|
||||
{},
|
||||
{
|
||||
default: false,
|
||||
},
|
||||
);
|
||||
Reference in New Issue
Block a user