Skip to content

Commit

Permalink
Support dark mode in SPA prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
range-of-motion committed Nov 19, 2023
1 parent 632d626 commit f88fdac
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 37 deletions.
2 changes: 2 additions & 0 deletions app/Http/Controllers/Api/LogInController.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public function __invoke(Request $request): JsonResponse
return response()
->json([
'token' => $apiKey->token,
'language' => Auth::user()->language,
'theme' => Auth::user()->theme,
]);
} else {
$userByEmail = User::query()
Expand Down
6 changes: 5 additions & 1 deletion app/Http/Controllers/Api/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public function store(Request $request): JsonResponse
$apiKey->user()->update(['theme' => $request->get('theme')]);
}

return response()->json([]);
return response()
->json([
'language' => $apiKey->user->language,
'theme' => $apiKey->user->theme,
]);
}
}
11 changes: 11 additions & 0 deletions resources/assets/js/prototype/components/App.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
<script setup>
const applyTheme = () => {
const dark = localStorage.getItem('theme') === 'dark';
const el = document.querySelector('html');
el.classList.add(dark ? 'dark' : 'light');
el.classList.remove(dark ? 'light' : 'dark');
};
applyTheme();
document.addEventListener('themeChanged', () => applyTheme());
</script>

<template>
Expand Down
12 changes: 6 additions & 6 deletions resources/assets/js/prototype/components/Navigation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,26 @@ const logOut = () => {
</script>

<template>
<div class="flex items-center h-16 bg-white border-b border-gray-200">
<div class="flex items-center h-16 bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
<div class="mx-auto flex-1 flex items-center justify-between max-w-5xl">
<div class="flex space-x-4">
<router-link class="flex items-center py-1 px-3 text-gray-500 hover:text-black" :to="{ name: 'dashboard' }">
<router-link class="flex items-center py-1 px-3 text-gray-500 dark:text-gray-400 hover:text-black dark:hover:text-white" :to="{ name: 'dashboard' }">
<Home :size="16" />
<span class="ml-2 text-sm">Dashboard</span>
</router-link>
<router-link class="flex items-center py-1 px-3 text-gray-500 hover:text-black" :to="{ name: 'transactions.index' }">
<router-link class="flex items-center py-1 px-3 text-gray-500 dark:text-gray-400 hover:text-black dark:hover:text-white" :to="{ name: 'transactions.index' }">
<ArrowRightLeft :size="16" />
<span class="ml-2 text-sm">Transactions</span>
</router-link>
</div>
<div class="flex items-center space-x-4">
<router-link class="flex py-1 px-3 text-gray-500 hover:text-black" :to="{ name: 'transactions.create' }">
<router-link class="flex py-1 px-3 text-gray-500 dark:text-gray-400 hover:text-black dark:hover:text-white" :to="{ name: 'transactions.create' }">
<PlusCircle :size="20" :strokeWidth="1.6" />
</router-link>
<router-link class="flex py-1 px-3 text-gray-500 hover:text-black" :to="{ name: 'settings.preferences' }">
<router-link class="flex py-1 px-3 text-gray-500 dark:text-gray-400 hover:text-black dark:hover:text-white" :to="{ name: 'settings.preferences' }">
<Settings2 :size="16" />
</router-link>
<button class="flex py-1 px-3 text-gray-500 hover:text-black" @click="logOut()">
<button class="flex py-1 px-3 text-gray-500 dark:text-gray-400 hover:text-black dark:hover:text-white" @click="logOut()">
<LogOut :size="16" />
</button>
</div>
Expand Down
2 changes: 1 addition & 1 deletion resources/assets/js/prototype/screens/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const getTimeSensitiveGreeting = () => {
<div class="my-10 mx-auto max-w-3xl">
<div class="flex flex-col items-center text-gray-400">
<Construction :size="32" :strokeWidth="1.5" />
<div class="mt-2 text-center text-sm text-gray-400">{{ getTimeSensitiveGreeting() }} and<br /> welcome to the prototype.</div>
<div class="mt-2 text-center text-sm">{{ getTimeSensitiveGreeting() }} and<br /> welcome to the prototype.</div>
</div>
</div>
</div>
Expand Down
16 changes: 10 additions & 6 deletions resources/assets/js/prototype/screens/Login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ const logIn = () => {
if (json.token) {
localStorage.setItem('api_key', json.token);
localStorage.setItem('theme', json.theme);
const e = new Event('themeChanged');
document.dispatchEvent(e);
router.push('dashboard');
}
Expand All @@ -31,16 +35,16 @@ const logIn = () => {

<template>
<div class="flex items-center justify-center min-h-screen">
<div class="flex-1 max-w-sm p-5 space-y-5 bg-white border rounded-lg">
<div class="flex-1 max-w-sm p-5 space-y-5 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg">
<div>
<label class="block mb-2 text-sm">E-mail</label>
<input class="w-full px-3.5 py-2.5 text-sm border rounded-lg" type="email" v-model="email" />
<label class="block mb-2 text-sm dark:text-white">E-mail</label>
<input class="w-full px-3.5 py-2.5 text-sm dark:text-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg" type="email" v-model="email" />
</div>
<div>
<label class="block mb-2 text-sm">Password</label>
<input class="w-full px-3.5 py-2.5 text-sm border rounded-lg" type="password" v-model="password" @keyup.enter="logIn" />
<label class="block mb-2 text-sm dark:text-white">Password</label>
<input class="w-full px-3.5 py-2.5 text-sm dark:text-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg" type="password" v-model="password" @keyup.enter="logIn" />
</div>
<button class="w-full py-3 text-sm text-white bg-gray-900 rounded-lg" @click="logIn">Log in</button>
<button class="w-full py-3 text-sm text-white bg-gray-900 dark:bg-gray-950 rounded-lg" @click="logIn">Log in</button>
</div>
</div>
</template>
17 changes: 11 additions & 6 deletions resources/assets/js/prototype/screens/Settings/Preferences.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@ const retrieve = () => {
const update = () => {
axios
.post('/api/settings', { language: language.value, theme: theme.value }, { headers: { 'api-key': localStorage.getItem('api_key') } })
.then(() => {
.then(response => {
// Done
localStorage.setItem('theme', response.data.theme);
const e = new Event('themeChanged');
document.dispatchEvent(e);
})
.catch(() => {
alert('Unable to save');
Expand All @@ -34,11 +39,11 @@ onMounted(() => retrieve());
<div>
<Navigation />
<div class="my-10 mx-auto max-w-3xl">
<div class="p-5 bg-white border border-gray-200 rounded-lg">
<div class="p-5 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg">
<div class="space-y-5 max-w-xs">
<div>
<div class="mb-2 text-sm">Language</div>
<select class="px-3.5 py-2.5 w-full text-sm border border-gray-200 rounded-lg appearance-none" v-model="language" @change="update">
<div class="mb-2 text-sm dark:text-white">Language</div>
<select class="px-3.5 py-2.5 w-full text-sm dark:text-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg appearance-none" v-model="language" @change="update">
<option value="en">English</option>
<option value="nl">Dutch</option>
<option value="dk">Danish</option>
Expand All @@ -49,8 +54,8 @@ onMounted(() => retrieve());
</select>
</div>
<div>
<div class="mb-2 text-sm">Theme</div>
<select class="px-3.5 py-2.5 w-full text-sm border border-gray-200 rounded-lg appearance-none" v-model="theme" @change="update">
<div class="mb-2 text-sm dark:text-white">Theme</div>
<select class="px-3.5 py-2.5 w-full text-sm dark:text-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg appearance-none" v-model="theme" @change="update">
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
Expand Down
24 changes: 12 additions & 12 deletions resources/assets/js/prototype/screens/Transactions/Create.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,28 @@ const create = () => {
<div>
<Navigation />
<div class="my-10 mx-auto max-w-sm">
<div class="p-5 space-y-5 bg-white border border-gray-200 rounded-lg">
<div class="p-5 space-y-5 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg">
<div class="flex space-x-3">
<button class="px-4 py-2.5 text-sm border border-gray-200 rounded-lg" :class="{ 'bg-gray-100': type === 'earning' }" @click="type = 'earning'">Earning</button>
<button class="px-4 py-2.5 text-sm border border-gray-200 rounded-lg" :class="{ 'bg-gray-100': type === 'spending' }" @click="type = 'spending'">Spending</button>
<button class="px-4 py-2.5 text-sm dark:text-white border border-gray-200 dark:border-gray-600 rounded-lg" :class="{ 'bg-gray-100 dark:bg-gray-700': type === 'earning' }" @click="type = 'earning'">Earning</button>
<button class="px-4 py-2.5 text-sm dark:text-white border border-gray-200 dark:border-gray-600 rounded-lg" :class="{ 'bg-gray-100 dark:bg-gray-700': type === 'spending' }" @click="type = 'spending'">Spending</button>
</div>
<div v-if="type === 'spending'">
<label class="mb-2 block text-sm">Tag</label>
<input class="w-full px-3.5 py-2.5 text-sm border rounded-lg" type="text" value="Coming soon" disabled />
<label class="mb-2 block text-sm dark:text-white">Tag</label>
<input class="w-full px-3.5 py-2.5 text-sm dark:text-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg" type="text" value="Coming soon" disabled />
</div>
<div>
<label class="mb-2 block text-sm">Date</label>
<input class="w-full px-3.5 py-2.5 text-sm border rounded-lg" type="text" v-model="happened_on" />
<label class="mb-2 block text-sm dark:text-white">Date</label>
<input class="w-full px-3.5 py-2.5 text-sm dark:text-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg" type="text" v-model="happened_on" />
</div>
<div>
<label class="mb-2 block text-sm">Description</label>
<input class="w-full px-3.5 py-2.5 text-sm border rounded-lg" type="text" :placeholder="type === 'earning' ? 'Paycheck February' : 'Birthday present for Angela'" v-model="description" />
<label class="mb-2 block text-sm dark:text-white">Description</label>
<input class="w-full px-3.5 py-2.5 text-sm dark:text-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg" type="text" :placeholder="type === 'earning' ? 'Paycheck February' : 'Birthday present for Angela'" v-model="description" />
</div>
<div>
<label class="mb-2 block text-sm">Amount</label>
<input class="w-full px-3.5 py-2.5 text-sm border rounded-lg" type="text" v-model="amount" />
<label class="mb-2 block text-sm dark:text-white">Amount</label>
<input class="w-full px-3.5 py-2.5 text-sm dark:text-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg" type="text" v-model="amount" />
</div>
<button class="w-full py-3 text-sm text-white bg-gray-900 rounded-lg" @click="create()">Create</button>
<button class="w-full py-3 text-sm text-white bg-gray-900 dark:bg-gray-950 rounded-lg" @click="create()">Create</button>
</div>
</div>
</div>
Expand Down
8 changes: 4 additions & 4 deletions resources/assets/js/prototype/screens/Transactions/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ onMounted(() => {
<div class="max-w-3xl mx-auto my-10 space-y-10">
<div v-for="span in spans" class="flex">
<div class="w-48">
<div class="font-medium">{{ getMonthName(span.month) }}</div>
<div class="mt-1 text-sm text-gray-500">{{ span.year }}</div>
<div class="font-medium dark:text-white">{{ getMonthName(span.month) }}</div>
<div class="mt-1 text-sm text-gray-500 dark:text-gray-400">{{ span.year }}</div>
</div>
<div class="flex-1">
<div class="py-4 px-5 space-y-2 bg-white rounded-lg border border-gray-200">
<div class="py-4 px-5 space-y-2 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg">
<div class="flex items-center justify-between" v-for="transaction in getTransactionsBySpan(span)">
<div class="text-sm text-gray-500">{{ transaction.description }}</div>
<div class="text-sm text-gray-500 dark:text-white">{{ transaction.description }}</div>
<div class="text-sm" :class="'text-' + (transaction.type === 'earning' ? 'green' : 'red') + '-600'">+{{ (transaction.amount / 100).toFixed(2) }}</div>
</div>
</div>
Expand Down
7 changes: 6 additions & 1 deletion resources/views/prototype.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
<html>
<head>
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
darkMode: 'class',
};
</script>
</head>
<body class="bg-gray-50">
<body class="bg-gray-50 dark:bg-gray-900">
<div id="app"></div>
@vite('resources/assets/js/prototype/app.js')
</body>
Expand Down

0 comments on commit f88fdac

Please sign in to comment.