Skip to content

Commit

Permalink
Merge pull request #467 from range-of-motion/translate-spa-prototype
Browse files Browse the repository at this point in the history
Translate SPA prototype
  • Loading branch information
range-of-motion authored Dec 16, 2023
2 parents 070677b + 537385e commit de60fd2
Show file tree
Hide file tree
Showing 14 changed files with 202 additions and 47 deletions.
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"axios": "^1.6.0",
"lucide-vue": "^0.292.0",
"vue-color": "^2.7.0",
"vue-i18n": "^8.28.2",
"vue-router": "3"
}
}
11 changes: 11 additions & 0 deletions resources/assets/js/prototype/app.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import ApexCharts from 'apexcharts';
import Vue from 'vue';
import VueI18n from 'vue-i18n'
import VueRouter from 'vue-router';

import translations from './translations';

import App from './components/App.vue';

import Login from './screens/Login.vue';
Expand All @@ -15,6 +18,8 @@ window.ApexCharts = ApexCharts;

Vue.prototype.versionNumber = window.versionNumber;

Vue.use(VueI18n);

Vue.use(VueRouter);

const routes = [
Expand Down Expand Up @@ -45,13 +50,19 @@ const routes = [
},
];

const i18n = new VueI18n({
locale: 'en',
messages: translations,
});

const router = new VueRouter({
mode: 'history',
routes,
});

new Vue({
el: '#app',
i18n,
router,
render: h => h(App),
});
17 changes: 15 additions & 2 deletions resources/assets/js/prototype/components/App.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
<script setup>
import { getCurrentInstance } from 'vue';
const i18n = getCurrentInstance().proxy.$i18n;
const applySettings = () => {
applyLocale();
applyTheme();
};
const applyLocale = () => {
i18n.locale = localStorage.getItem('language');
};
const applyTheme = () => {
const dark = localStorage.getItem('theme') === 'dark';
Expand All @@ -8,9 +21,9 @@ const applyTheme = () => {
el.classList.remove(dark ? 'light' : 'dark');
};
applyTheme();
applySettings();
document.addEventListener('themeChanged', () => applyTheme());
document.addEventListener('settingsChanged', () => applySettings());
</script>

<template>
Expand Down
4 changes: 2 additions & 2 deletions resources/assets/js/prototype/components/Navigation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ const logOut = () => {
<div class="flex space-x-4">
<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>
<span class="ml-2 text-sm">{{ $t('dashboard') }}</span>
</router-link>
<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>
<span class="ml-2 text-sm">{{ $t('transactions') }}</span>
</router-link>
</div>
<div class="flex items-center space-x-4">
Expand Down
2 changes: 1 addition & 1 deletion resources/assets/js/prototype/screens/Activities.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fetchActivities();
<div class="absolute -left-2.5 w-5 h-5 bg-gray-100 border border-gray-300 ring-8 ring-white rounded-full"></div>
<div class="pl-5">
<div class="-mt-px text-sm">
<span>{{ activity.user ? activity.user.name : 'Budget' }} {{ activity.action.split('.')[1] }} {{ activity.action.split('.')[0] }} #{{ activity.entity_id }}</span>
<span>{{ activity.user ? activity.user.name : 'Budget' }} {{ $t('activities.' + activity.action, { id: activity.entity_id }) }}</span>
</div>
<div class="mt-1 text-xs text-gray-500">{{ new Date(activity.occurred_at).toJSON().split('T')[0] }}</div>
</div>
Expand Down
10 changes: 5 additions & 5 deletions resources/assets/js/prototype/screens/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ const getTimeSensitiveGreeting = () => {
const hour = new Date().getHours();
if (hour < 12) {
return 'Good morning';
return 'goodMorning';
} else if (hour < 18) {
return 'Good afternoon';
return 'goodAfternoon';
} else {
return 'Good evening';
return 'goodEvening';
}
};
Expand Down Expand Up @@ -88,8 +88,8 @@ onMounted(() => {
<Navigation />
<div class="my-10 mx-auto max-w-3xl">
<div class="mb-5">
<div class="font-medium">{{ getTimeSensitiveGreeting() }}</div>
<div class="mt-1 text-sm text-gray-500">Here is your balance throughout the month</div>
<div class="font-medium">{{ $t(getTimeSensitiveGreeting()) }}</div>
<div class="mt-1 text-sm text-gray-500">{{ $t('dailyBalanceGraphDescription') }}</div>
</div>
<div class="p-5 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg">
<div id="chart"></div>
Expand Down
10 changes: 5 additions & 5 deletions resources/assets/js/prototype/screens/Login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ const logIn = () => {
if (json.token) {
localStorage.setItem('api_key', json.token);
localStorage.setItem('language', json.language);
localStorage.setItem('theme', json.theme);
const e = new Event('themeChanged');
document.dispatchEvent(e);
document.dispatchEvent(new Event('settingsChanged'));
router.push('dashboard');
}
Expand All @@ -38,14 +38,14 @@ const logIn = () => {
<div class="flex-1 max-w-sm">
<div class="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 dark:text-white">E-mail</label>
<label class="block mb-2 text-sm dark:text-white">{{ $t('email') }}</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 dark:text-white">Password</label>
<label class="block mb-2 text-sm dark:text-white">{{ $t('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 dark:bg-gray-950 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">{{ $t('logIn') }}</button>
</div>
<div class="mt-5 text-sm text-center dark:text-white">{{ versionNumber }}</div>
</div>
Expand Down
10 changes: 5 additions & 5 deletions resources/assets/js/prototype/screens/Settings/Preferences.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ const update = () => {
.then(response => {
// Done
localStorage.setItem('language', response.data.language);
localStorage.setItem('theme', response.data.theme);
const e = new Event('themeChanged');
document.dispatchEvent(e);
document.dispatchEvent(new Event('settingsChanged'));
})
.catch(() => {
alert('Unable to save');
Expand All @@ -50,7 +50,7 @@ onMounted(() => retrieve());
<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 dark:text-white">Language</div>
<div class="mb-2 text-sm dark:text-white">{{ $t('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>
Expand All @@ -62,14 +62,14 @@ onMounted(() => retrieve());
</select>
</div>
<div>
<div class="mb-2 text-sm dark:text-white">Theme</div>
<div class="mb-2 text-sm dark:text-white">{{ $t('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>
</div>
<div>
<div class="mb-2 text-sm dark:text-white">Weekly report</div>
<div class="mb-2 text-sm dark:text-white">{{ $t('weeklyReport') }}</div>
<button class="relative flex w-9 h-6 bg-gray-200 rounded-full" :class="{ 'bg-gray-900': weeklyReport }" @click="toggleWeeklyReport()">
<span class="absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full" :class="{ 'left-auto right-0.5': weeklyReport }"></span>
</button>
Expand Down
28 changes: 14 additions & 14 deletions resources/assets/js/prototype/screens/Transactions/Create.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,40 +75,40 @@ fetchTags();
<div class="my-10 mx-auto max-w-sm">
<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 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>
<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'">{{ $t('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'">{{ $t('spending') }}</button>
</div>
<div v-if="type === 'spending'">
<label class="mb-2 block text-sm dark:text-white">Tag</label>
<label class="mb-2 block text-sm dark:text-white">{{ $t('tag') }}</label>
<select 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 appearance-none" v-model="tagId">
<option :value="null">-</option>
<option v-for="tag in tags" :key="tag.id" :value="tag.id">{{ tag.name }}</option>
</select>
</div>
<div>
<label class="mb-2 block text-sm dark:text-white">Date</label>
<label class="mb-2 block text-sm dark:text-white">{{ $t('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="happenedOn" />
</div>
<div>
<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" />
<label class="mb-2 block text-sm dark:text-white">{{ $t('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' ? $t('earningDescriptionPlaceholder') : $t('spendingDescriptionPlaceholder')" v-model="description" />
</div>
<div>
<label class="mb-2 block text-sm dark:text-white">Amount</label>
<label class="mb-2 block text-sm dark:text-white">{{ $t('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>
<div class="flex space-x-2">
<button class="mt-0.5 w-5 h-5 border rounded-md" :class="{ 'bg-gray-900 border-none': isRecurring }" @click="isRecurring = !isRecurring"></button>
<button class="flex-1 text-left text-sm dark:text-white" @click="isRecurring = !isRecurring">This is a recurring transaction—create it for me in the future</button>
<button class="flex-1 text-left text-sm dark:text-white" @click="isRecurring = !isRecurring">{{ $t('recurringDescription') }}</button>
</div>
<div v-if="isRecurring" class="flex flex-wrap gap-2">
<button class="px-3 py-2 text-sm border border-gray-200 rounded-lg" :class="{ 'bg-gray-100': recurringInterval === 'yearly' }" @click="recurringInterval = 'yearly'">Yearly</button>
<button class="px-3 py-2 text-sm border border-gray-200 rounded-lg" :class="{ 'bg-gray-100': recurringInterval === 'monthly' }" @click="recurringInterval = 'monthly'">Monthly</button>
<button class="px-3 py-2 text-sm border border-gray-200 rounded-lg" :class="{ 'bg-gray-100': recurringInterval === 'biweekly' }" @click="recurringInterval = 'biweekly'">Biweekly</button>
<button class="px-3 py-2 text-sm border border-gray-200 rounded-lg" :class="{ 'bg-gray-100': recurringInterval === 'weekly' }" @click="recurringInterval = 'weekly'">Weekly</button>
<button class="px-3 py-2 text-sm border border-gray-200 rounded-lg" :class="{ 'bg-gray-100': recurringInterval === 'daily' }" @click="recurringInterval = 'daily'">Daily</button>
<button class="px-3 py-2 text-sm border border-gray-200 rounded-lg" :class="{ 'bg-gray-100': recurringInterval === 'yearly' }" @click="recurringInterval = 'yearly'">{{ $t('intervals.yearly') }}</button>
<button class="px-3 py-2 text-sm border border-gray-200 rounded-lg" :class="{ 'bg-gray-100': recurringInterval === 'monthly' }" @click="recurringInterval = 'monthly'">{{ $t('intervals.monthly') }}</button>
<button class="px-3 py-2 text-sm border border-gray-200 rounded-lg" :class="{ 'bg-gray-100': recurringInterval === 'biweekly' }" @click="recurringInterval = 'biweekly'">{{ $t('intervals.biweekly') }}</button>
<button class="px-3 py-2 text-sm border border-gray-200 rounded-lg" :class="{ 'bg-gray-100': recurringInterval === 'weekly' }" @click="recurringInterval = 'weekly'">{{ $t('intervals.weekly') }}</button>
<button class="px-3 py-2 text-sm border border-gray-200 rounded-lg" :class="{ 'bg-gray-100': recurringInterval === 'daily' }" @click="recurringInterval = 'daily'">{{ $t('intervals.daily') }}</button>
</div>
<button class="w-full py-3 text-sm text-white bg-gray-900 dark:bg-gray-950 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()">{{ $t('create') }}</button>
</div>
</div>
</div>
Expand Down
26 changes: 13 additions & 13 deletions resources/assets/js/prototype/screens/Transactions/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ const spans = computed(() => {
const getMonthName = (month) => {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
'january',
'february',
'march',
'april',
'may',
'june',
'july',
'august',
'september',
'october',
'november',
'december',
];
return months[month - 1];
Expand Down Expand Up @@ -79,7 +79,7 @@ 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 dark:text-white">{{ getMonthName(span.month) }}</div>
<div class="font-medium dark:text-white">{{ $t('months.' + 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">
Expand Down
59 changes: 59 additions & 0 deletions resources/assets/js/prototype/translations/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"amount": "Amount",
"create": "Create",
"dailyBalanceGraphDescription": "Here is your balance throughout the month",
"dashboard": "Dashboard",
"date": "Date",
"description": "Description",
"earning": "Earning",
"earningDescriptionPlaceholder": "Paycheck February",
"email": "E-mail",
"goodAfternoon": "Good afternoon",
"goodEvening": "Good evening",
"goodMorning": "Good morning",
"language": "Language",
"logIn": "Log in",
"password": "Password",
"recurringDescription": "This is a recurring transaction—create it for me in the future",
"spending": "Spending",
"spendingDescriptionPlaceholder": "Birthday present for Angela",
"tag": "Tag",
"theme": "Theme",
"transactions": "Transactions",
"weeklyReport": "Weekly report",

"activities": {
"tag": {
"created": "created tag #{id}",
"deleted": "deleted tag #{id}"
},

"transaction": {
"created": "created transaction #{id}",
"deleted": "deleted transaction #{id}"
}
},

"intervals": {
"daily": "Daily",
"weekly": "Weekly",
"biweekly": "Biweekly",
"monthly": "Monthly",
"yearly": "Yearly"
},

"months": {
"january": "January",
"february": "February",
"march": "March",
"april": "April",
"may": "May",
"june": "June",
"july": "July",
"august": "August",
"september": "September",
"october": "October",
"november": "November",
"december": "December"
}
}
7 changes: 7 additions & 0 deletions resources/assets/js/prototype/translations/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as en from './en.json';
import * as nl from './nl.json';

export default {
en,
nl,
};
Loading

0 comments on commit de60fd2

Please sign in to comment.