Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support dark mode in SPA prototype #442

Merged
merged 1 commit into from
Nov 19, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/Http/Controllers/Api/LogInController.php
Original file line number Diff line number Diff line change
@@ -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()
6 changes: 5 additions & 1 deletion app/Http/Controllers/Api/SettingsController.php
Original file line number Diff line number Diff line change
@@ -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>
12 changes: 6 additions & 6 deletions resources/assets/js/prototype/components/Navigation.vue
Original file line number Diff line number Diff line change
@@ -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>
2 changes: 1 addition & 1 deletion resources/assets/js/prototype/screens/Dashboard.vue
Original file line number Diff line number Diff line change
@@ -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>
16 changes: 10 additions & 6 deletions resources/assets/js/prototype/screens/Login.vue
Original file line number Diff line number Diff line change
@@ -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');
}
@@ -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
@@ -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');
@@ -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>
@@ -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>
24 changes: 12 additions & 12 deletions resources/assets/js/prototype/screens/Transactions/Create.vue
Original file line number Diff line number Diff line change
@@ -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>
8 changes: 4 additions & 4 deletions resources/assets/js/prototype/screens/Transactions/Index.vue
Original file line number Diff line number Diff line change
@@ -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>
7 changes: 6 additions & 1 deletion resources/views/prototype.blade.php
Original file line number Diff line number Diff line change
@@ -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>