Skip to content

Commit 5bda8f3

Browse files
authored
Dark Mode (#14)
* Add ThemeChange * Add ThemeSwitcher Component * Fix Light/Dark Theming
1 parent 923971f commit 5bda8f3

File tree

4 files changed

+138
-54
lines changed

4 files changed

+138
-54
lines changed

frontend/package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
},
1515
"dependencies": {
1616
"@tailwindcss/vite": "^4.1.14",
17+
"theme-change": "^2.5.0",
1718
"vue": "^3.5.22"
1819
},
1920
"devDependencies": {

frontend/src/App.vue

Lines changed: 88 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,102 @@
11
<template>
2-
<div class="min-h-screen w-full flex flex-col">
3-
<div class="navbar bg-base-100 shadow-sm">
4-
<div class="flex items-center gap-4 lg:ml-20">
5-
<img src="/logo.svg" alt="CertUI Logo" class="h-15" />
6-
<span class="text-2xl font-bold">CertUI</span>
7-
</div>
8-
</div>
9-
10-
<div class="p-5 flex-1 bg-gray-50">
11-
<div class="max-w-6xl mx-auto">
12-
<div class="my-4" v-if="endpointsData.length" v-for="(endpointData, index) in endpointsData" :key="index">
13-
<div v-if="endpointData.ssl" class="collapse collapse-arrow bg-base-100 border border-base-300">
14-
<input type="radio" name="certificate-accordion" />
15-
<div class="collapse-title font-semibold">
16-
{{ endpointData.endpoint }}
17-
<ExpiryStatus class="ml-4" :ssl="endpointData.ssl" :daysRemainingLimit="14" />
2+
<div class="min-h-screen w-full flex flex-col">
3+
<div class="navbar bg-base-100 shadow-sm">
4+
<div class="flex items-center gap-4 lg:ml-20">
5+
<img src="/logo.svg" alt="CertUI Logo" class="h-15" />
6+
<span class="text-2xl font-bold">CertUI</span>
187
</div>
19-
<div class="collapse-content">
20-
<EndpointCard
21-
class="p-5"
22-
:endpoint="endpointData.endpoint"
23-
:ssl="endpointData.ssl" />
24-
</div>
25-
</div>
268
</div>
27-
<div v-else class="text-center text-gray-500 italic">
28-
No endpoints.
9+
10+
<div class="p-5 flex-1 bg-base-200">
11+
<div class="max-w-6xl mx-auto">
12+
<div
13+
class="my-4"
14+
v-if="endpointsData.length"
15+
v-for="(endpointData, index) in endpointsData"
16+
:key="index"
17+
>
18+
<div
19+
v-if="endpointData.ssl"
20+
class="collapse collapse-arrow bg-base-100 border border-base-300"
21+
>
22+
<input type="radio" name="certificate-accordion" />
23+
<div class="collapse-title font-semibold">
24+
{{ endpointData.endpoint }}
25+
<ExpiryStatus
26+
class="ml-4"
27+
:ssl="endpointData.ssl"
28+
:daysRemainingLimit="14"
29+
/>
30+
</div>
31+
<div class="collapse-content">
32+
<EndpointCard
33+
class="p-5"
34+
:endpoint="endpointData.endpoint"
35+
:ssl="endpointData.ssl"
36+
/>
37+
</div>
38+
</div>
39+
</div>
40+
<div v-else class="text-center italic">No endpoints.</div>
41+
</div>
2942
</div>
30-
</div>
31-
</div>
3243

33-
<footer class="p-4 bg-gray-200 flex items-center justify-between">
34-
<aside class="text-left">
35-
Powered by <a href="https://github.com/ben-burwood/certui" target="_blank" class="font-medium text-green-800 hover:text-green-600">CertUI</a>
36-
</aside>
37-
<nav class="text-right">
38-
<a href="https://github.com/ben-burwood/certui" target="_blank" title="CertUI on GitHub">
39-
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 16 16" class="hover:scale-110">
40-
<path fill="gray"
41-
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z" />
42-
</svg>
43-
</a>
44-
</nav>
45-
</footer>
46-
</div>
44+
<footer class="p-4 bg-base-300 flex items-center justify-between">
45+
<aside class="text-left">
46+
Powered by
47+
<a
48+
href="https://github.com/ben-burwood/certui"
49+
target="_blank"
50+
class="font-medium text-green-800 hover:text-green-600"
51+
>CertUI</a
52+
>
53+
</aside>
54+
<ThemeSwitcher />
55+
<nav class="text-right">
56+
<a
57+
href="https://github.com/ben-burwood/certui"
58+
target="_blank"
59+
title="CertUI on GitHub"
60+
>
61+
<svg
62+
xmlns="http://www.w3.org/2000/svg"
63+
width="32"
64+
height="32"
65+
viewBox="0 0 16 16"
66+
class="hover:scale-110"
67+
>
68+
<path
69+
fill="gray"
70+
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"
71+
/>
72+
</svg>
73+
</a>
74+
</nav>
75+
</footer>
76+
</div>
4777
</template>
4878

4979
<script setup lang="ts">
50-
import EndpointCard from '@/components/EndpointCard.vue';
51-
import { SERVER_URL } from '@/main';
52-
import type { SSLDetails } from '@/types/certificate';
53-
import { onMounted, ref } from 'vue';
54-
import ExpiryStatus from './components/ExpiryStatus.vue';
80+
import ThemeSwitcher from "./components/ThemeSwitcher.vue";
81+
import EndpointCard from "@/components/EndpointCard.vue";
82+
import { SERVER_URL } from "@/main";
83+
import type { SSLDetails } from "@/types/certificate";
84+
import { onMounted, ref } from "vue";
85+
import ExpiryStatus from "./components/ExpiryStatus.vue";
5586
5687
const endpointsData = ref<{ endpoint: string; ssl: SSLDetails | null }[]>([]);
5788
5889
onMounted(async () => {
59-
try {
60-
const res = await fetch(`${SERVER_URL}/endpoints`);
61-
const data: Record<string, SSLDetails | null> = await res.json();
62-
endpointsData.value = Object.entries(data).map(([endpoint, ssl]) => ({ endpoint, ssl }));
63-
} catch (e) {
64-
console.error('Failed to fetch endpoints:', e);
65-
endpointsData.value = [];
66-
}
90+
try {
91+
const res = await fetch(`${SERVER_URL}/endpoints`);
92+
const data: Record<string, SSLDetails | null> = await res.json();
93+
endpointsData.value = Object.entries(data).map(([endpoint, ssl]) => ({
94+
endpoint,
95+
ssl,
96+
}));
97+
} catch (e) {
98+
console.error("Failed to fetch endpoints:", e);
99+
endpointsData.value = [];
100+
}
67101
});
68102
</script>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<template>
2+
<label class="swap swap-rotate">
3+
<!-- this hidden checkbox controls the state -->
4+
<input
5+
type="checkbox"
6+
class="theme-controller"
7+
value="synthwave"
8+
data-toggle-theme="dark"
9+
/>
10+
11+
<!-- sun icon -->
12+
<svg
13+
class="swap-off h-10 w-10 fill-current"
14+
xmlns="http://www.w3.org/2000/svg"
15+
viewBox="0 0 24 24"
16+
>
17+
<path
18+
d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z"
19+
/>
20+
</svg>
21+
22+
<!-- moon icon -->
23+
<svg
24+
class="swap-on h-10 w-10 fill-current"
25+
xmlns="http://www.w3.org/2000/svg"
26+
viewBox="0 0 24 24"
27+
>
28+
<path
29+
d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z"
30+
/>
31+
</svg>
32+
</label>
33+
</template>
34+
35+
<script setup lang="ts">
36+
import { themeChange } from "theme-change";
37+
import { onMounted } from "vue";
38+
39+
onMounted(() => {
40+
themeChange(false);
41+
});
42+
</script>

0 commit comments

Comments
 (0)