From 1eb62066403d8a90ca9b0695a973a1cf9fbc1656 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Nov=C3=A1k?=
Date: Mon, 31 Aug 2026 23:43:37 +0200
Subject: [PATCH 1/2] Move hardcoded texts from components to localization file
---
i18n/messages/en.json | 66 +++++++++++++++-
.../components/dashboard/ActivityFeed.svelte | 3 +-
.../components/dashboard/DonutChart.svelte | 3 +-
.../dashboard/StackedAreaChart.svelte | 14 +++-
.../dashboard/VehicleFilterDropdown.svelte | 7 +-
.../dashboard/VehicleLeaderboard.svelte | 3 +-
.../components/dashboard/widget-registry.ts | 77 ++++++++++---------
.../dashboard/widgets/CalendarWidget.svelte | 3 +-
.../widgets/FuelConsumptionTrendWidget.svelte | 3 +-
.../widgets/MileageOverviewWidget.svelte | 3 +-
.../widgets/UpcomingRemindersWidget.svelte | 3 +-
.../widgets/VehicleQuickListWidget.svelte | 3 +-
.../feature/dashboard/AddWidgetPanel.svelte | 3 +-
src/lib/components/layout/AppSidebar.svelte | 20 ++---
src/routes/(app)/dashboard/+page.svelte | 44 ++++++++---
src/routes/(app)/fuel/+page.svelte | 8 +-
src/routes/(app)/garage/+page.svelte | 9 ++-
17 files changed, 191 insertions(+), 81 deletions(-)
diff --git a/i18n/messages/en.json b/i18n/messages/en.json
index fb0349ca..888c28ef 100644
--- a/i18n/messages/en.json
+++ b/i18n/messages/en.json
@@ -98,10 +98,15 @@
"common_date_from": "From",
"common_date_to": "To",
"common_export_csv": "Export CSV",
+ "nav_garage": "Garage",
+ "nav_dashboard": "Dashboard",
"nav_overview": "Overview",
"nav_fuel_logs": "Fuel Logs",
+ "nav_logs": "Logs",
+ "nav_insights": "Insights",
"nav_maintenance": "Maintenance",
"nav_reminders": "Reminders",
+ "nav_reports": "Reports",
"tools_export_data": "Export Data",
"tools_import_data": "Import Data",
"vehicle_form_make_label": "Make",
@@ -672,6 +677,7 @@
"fuel_stat_spent": "Total Spent",
"fuel_stat_avg_mileage": "Avg Mileage",
"fuel_stat_entries": "Total Entries",
+ "donut_chart_no_data": "No data available",
"maintenance_page_title": "Maintenance",
"maintenance_page_description": "Track service history and upcoming maintenance",
"maintenance_stat_last_service": "Last Service",
@@ -715,6 +721,7 @@
"reports_section_costs": "Costs",
"reports_section_details": "Detailed Report",
"reports_section_exports": "Exports",
+ "reports_no_expense_data": "No expense data yet",
"reports_stat_fuel_costs": "Fuel Costs",
"reports_stat_maintenance_costs": "Maintenance Costs",
"reports_chart_breakdown_title": "Expense Breakdown",
@@ -809,5 +816,62 @@
"reports_stat_compliance_costs": "Compliance Costs",
"compliance_col_document": "Compliance",
"compliance_col_status": "Status",
- "compliance_col_days_left": "Days Left"
+ "compliance_col_days_left": "Days Left",
+ "vehicles_title": "Vehicles",
+ "vehicles_description": "Manage your fleet",
+ "no_data_yet": "No data yet",
+ "dashboard_title": "Dashboard",
+ "dashboard_reset_to_default": "Reset to Default",
+ "dashboard_reset_confirm_title": "Reset dashboard?",
+ "dashboard_reset_confirm_message": "This restores the default set of widgets and layout, replacing your current customization.",
+ "dashboard_reset_confirm_reset": "Reset",
+ "dashboard_add_widget": "Add Widget",
+ "dashboard_good_morning": "Good morning",
+ "dashboard_good_afternoon": "Good afternoon",
+ "dashboard_good_evening": "Good evening",
+ "dashboard_cta_heading": "Get detailed insights",
+ "dashboard_cta_description": "View comprehensive reports and analytics for your fleet",
+ "dashboard_cta_button_label": "View Reports",
+ "all_widgets_used": "All available widgets are already on your dashboard.",
+ "widget_total_vehicles": "Total Vehicles",
+ "widget_total_vehicles_description": "Number of vehicles in your garage",
+ "widget_total_distance": "Total Distance",
+ "widget_total_distance_description": "Distance driven across the whole fleet",
+ "widget_total_fuel_used": "Total Fuel Used",
+ "widget_total_fuel_used_description": "Fuel consumed across the whole fleet",
+ "widget_total_expenses": "Total Expenses",
+ "widget_total_expenses_description": "Fuel, maintenance and insurance spend combined",
+ "widget_cost_per_distance": "Cost / Distance",
+ "widget_cost_per_distance_description": "Overall running cost per unit distance",
+ "widget_expense_breakdown": "Expenses by Category",
+ "widget_expense_breakdown_description": "Fuel vs. maintenance vs. compliance spend",
+ "widget_monthly_expense_trend": "Monthly Expense Trend",
+ "widget_monthly_expense_trend_description": "Last 12 months of spend by category",
+ "widget_cost_by_vehicle": "Cost by Vehicle",
+ "widget_cost_by_vehicle_description": "Which vehicles cost the most to run",
+ "widget_fleet_fuel_trend": "Fleet Fuel Trend",
+ "widget_fleet_fuel_trend_description": "Daily fuel usage across the fleet",
+ "widget_fuel_consumption_trend": "Fuel Consumption Trend",
+ "widget_fuel_consumption_trend_description": "Fuel usage over time, one line per vehicle",
+ "widget_mileage_overview": "Mileage Overview",
+ "widget_mileage_overview_description": "Mileage over time, one line per vehicle",
+ "widget_efficiency_leaderboard": "Efficiency Leaderboard",
+ "widget_efficiency_leaderboard_description": "Vehicles ranked by fuel efficiency",
+ "widget_compliance_status": "Other Compliance Status",
+ "widget_compliance_status_description": "Emissions, roadworthiness & registration status across the fleet",
+ "widget_insurance_status": "Insurance Status",
+ "widget_insurance_status_description": "Insurance policy status across the fleet",
+ "widget_vehicle_health": "Vehicle Health",
+ "widget_vehicle_health_description": "Overall good/attention/needs-action breakdown",
+ "widget_upcoming_reminders": "Upcoming Reminders",
+ "widget_upcoming_reminders_description": "Reminders coming due soon",
+ "widget_no_upcoming_reminders": "No upcoming reminders",
+ "widget_vehicles_quick_list": "My Vehicles",
+ "widget_vehicles_quick_list_description": "Quick access to your vehicles",
+ "widget_no_vehicles_yet": "No vehicles yet",
+ "widget_recent_activity": "Recent Activity",
+ "widget_recent_activity_description": "Latest fuel and maintenance logs across the fleet",
+ "widget_activity_calendar": "Activity Calendar",
+ "widget_activity_calendar_description": "Upcoming reminders and past fuel/maintenance activity by date",
+ "widget_calendar_no_activity_or_reminders": "No activity or reminders on this date."
}
diff --git a/src/lib/components/dashboard/ActivityFeed.svelte b/src/lib/components/dashboard/ActivityFeed.svelte
index d84d7f8c..42dffb61 100644
--- a/src/lib/components/dashboard/ActivityFeed.svelte
+++ b/src/lib/components/dashboard/ActivityFeed.svelte
@@ -5,6 +5,7 @@
import Skeleton from '$lib/components/ui/skeleton/skeleton.svelte';
import { formatCurrency, formatDate } from '$lib/helper/format.helper';
import { ACCENT } from '$lib/helper/accent-color.helper';
+ import { vehicle_hub_activity_empty } from '$lib/paraglide/messages/_index.js';
let {
entries,
@@ -27,7 +28,7 @@
{:else if entries.length === 0}
- No recent activity
+ {vehicle_hub_activity_empty()}
{:else}
diff --git a/src/lib/components/dashboard/DonutChart.svelte b/src/lib/components/dashboard/DonutChart.svelte
index b3d8e993..c76a65de 100644
--- a/src/lib/components/dashboard/DonutChart.svelte
+++ b/src/lib/components/dashboard/DonutChart.svelte
@@ -2,6 +2,7 @@
import * as Chart from '$ui/chart/index.js';
import { PieChart } from 'layerchart';
import Skeleton from '$lib/components/ui/skeleton/skeleton.svelte';
+ import { donut_chart_no_data } from '$lib/paraglide/messages/_index.js';
interface DonutDataPoint {
name: string;
@@ -125,7 +126,7 @@
class="flex flex-col items-center justify-center gap-2 {chartAreaClass}"
style={chartStyle}
>
- No data available
+ {donut_chart_no_data()}
{:else if data.length === 1}
{@const size = ringSize}
diff --git a/src/lib/components/dashboard/StackedAreaChart.svelte b/src/lib/components/dashboard/StackedAreaChart.svelte
index 3ba00cee..dac2cce4 100644
--- a/src/lib/components/dashboard/StackedAreaChart.svelte
+++ b/src/lib/components/dashboard/StackedAreaChart.svelte
@@ -9,6 +9,12 @@
import LegendInfoGroup from '$appui/LegendInfoGroup.svelte';
import CircleSlash2 from '@lucide/svelte/icons/circle-slash-2';
import Skeleton from '$lib/components/ui/skeleton/skeleton.svelte';
+ import {
+ reports_no_expense_data,
+ reports_type_fuel,
+ reports_type_maintenance,
+ reports_type_compliance
+ } from '$lib/paraglide/messages/_index.js';
let {
data,
@@ -24,9 +30,9 @@
} = $props();
const SERIES = [
- { key: 'fuel', label: 'Fuel', color: 'var(--chart-1)' },
- { key: 'maintenance', label: 'Maintenance', color: 'var(--chart-2)' },
- { key: 'compliance', label: 'Compliance', color: 'var(--chart-3)' }
+ { key: 'fuel', label: reports_type_fuel(), color: 'var(--chart-1)' },
+ { key: 'maintenance', label: reports_type_maintenance(), color: 'var(--chart-2)' },
+ { key: 'compliance', label: reports_type_compliance(), color: 'var(--chart-3)' }
] as const;
const chartData = $derived(data.map((point) => ({ ...point, x: new Date(`${point.month}-01`) })));
@@ -136,7 +142,7 @@
{:else}
-
+
{/if}
diff --git a/src/lib/components/dashboard/VehicleFilterDropdown.svelte b/src/lib/components/dashboard/VehicleFilterDropdown.svelte
index 90d6db14..2497512b 100644
--- a/src/lib/components/dashboard/VehicleFilterDropdown.svelte
+++ b/src/lib/components/dashboard/VehicleFilterDropdown.svelte
@@ -7,6 +7,7 @@
import type { Vehicle } from '$lib/domain/vehicle';
import VehicleTypeBadge from '$feature/vehicle/VehicleTypeBadge.svelte';
import { cn } from '$lib/utils';
+ import { vehicle_scope_all } from '$lib/paraglide/messages/_index.js';
let {
vehicles,
@@ -23,9 +24,9 @@
);
const triggerLabel = $derived.by(() => {
- if (selectedIds.length === 0) return 'All Vehicles';
+ if (selectedIds.length === 0) return vehicle_scope_all();
if (selectedIds.length === 1)
- return singleSelected ? vehicleLabel(singleSelected) : 'All Vehicles';
+ return singleSelected ? vehicleLabel(singleSelected) : vehicle_scope_all();
return `${selectedIds.length} vehicles`;
});
@@ -57,7 +58,7 @@
(selectedIds = [])}>
0 && 'text-transparent')} />
- All Vehicles
+ {vehicle_scope_all()}
{#if vehicles.length > 0}
diff --git a/src/lib/components/dashboard/VehicleLeaderboard.svelte b/src/lib/components/dashboard/VehicleLeaderboard.svelte
index 0ea73ca4..316885a1 100644
--- a/src/lib/components/dashboard/VehicleLeaderboard.svelte
+++ b/src/lib/components/dashboard/VehicleLeaderboard.svelte
@@ -2,6 +2,7 @@
import Skeleton from '$lib/components/ui/skeleton/skeleton.svelte';
import { cn } from '$lib/utils';
import { ACCENT } from '$lib/helper/accent-color.helper';
+ import { no_data_yet } from '$lib/paraglide/messages/_index.js';
interface Entry {
id: string;
@@ -13,7 +14,7 @@
let {
entries,
loading = false,
- emptyLabel = 'No data yet'
+ emptyLabel = no_data_yet()
}: {
entries: Entry[];
loading?: boolean;
diff --git a/src/lib/components/dashboard/widget-registry.ts b/src/lib/components/dashboard/widget-registry.ts
index d751f655..04af89a4 100644
--- a/src/lib/components/dashboard/widget-registry.ts
+++ b/src/lib/components/dashboard/widget-registry.ts
@@ -19,6 +19,7 @@ import Route from '@lucide/svelte/icons/route';
import Fuel from '@lucide/svelte/icons/fuel';
import DollarSign from '@lucide/svelte/icons/dollar-sign';
import CircleGauge from '@lucide/svelte/icons/circle-gauge';
+import * as w from '$lib/paraglide/messages/_index.js';
interface WidgetDefinition {
type: WidgetType;
@@ -36,8 +37,8 @@ interface WidgetDefinition {
export const WIDGET_REGISTRY: Record = {
'stat-vehicle-count': {
type: 'stat-vehicle-count',
- title: 'Total Vehicles',
- description: 'Number of vehicles in your garage',
+ title: w.widget_total_vehicles(),
+ description: w.widget_total_vehicles_description(),
component: FleetStatWidget,
extraProps: { metric: 'vehicle-count' },
defaultColSpan: 3,
@@ -47,8 +48,8 @@ export const WIDGET_REGISTRY: Record = {
},
'stat-total-distance': {
type: 'stat-total-distance',
- title: 'Total Distance',
- description: 'Distance driven across the whole fleet',
+ title: w.widget_total_distance(),
+ description: w.widget_total_distance_description(),
component: FleetStatWidget,
extraProps: { metric: 'total-distance' },
defaultColSpan: 3,
@@ -58,8 +59,8 @@ export const WIDGET_REGISTRY: Record = {
},
'stat-fuel-used': {
type: 'stat-fuel-used',
- title: 'Total Fuel Used',
- description: 'Fuel consumed across the whole fleet',
+ title: w.widget_total_fuel_used(),
+ description: w.widget_total_fuel_used_description(),
component: FleetStatWidget,
extraProps: { metric: 'fuel-used' },
defaultColSpan: 3,
@@ -69,8 +70,8 @@ export const WIDGET_REGISTRY: Record = {
},
'stat-total-expenses': {
type: 'stat-total-expenses',
- title: 'Total Expenses',
- description: 'Fuel, maintenance and insurance spend combined',
+ title: w.widget_total_expenses(),
+ description: w.widget_total_expenses_description(),
component: FleetStatWidget,
extraProps: { metric: 'total-expenses' },
defaultColSpan: 3,
@@ -80,8 +81,8 @@ export const WIDGET_REGISTRY: Record = {
},
'stat-cost-per-distance': {
type: 'stat-cost-per-distance',
- title: 'Cost / Distance',
- description: 'Overall running cost per unit distance',
+ title: w.widget_cost_per_distance(),
+ description: w.widget_cost_per_distance_description(),
component: FleetStatWidget,
extraProps: { metric: 'cost-per-distance' },
defaultColSpan: 3,
@@ -91,24 +92,24 @@ export const WIDGET_REGISTRY: Record = {
},
'expense-breakdown-donut': {
type: 'expense-breakdown-donut',
- title: 'Expenses by Category',
- description: 'Fuel vs. maintenance vs. compliance spend',
+ title: w.widget_expense_breakdown(),
+ description: w.widget_expense_breakdown_description(),
component: ExpenseBreakdownWidget,
defaultColSpan: 6,
defaultRowSpan: 8
},
'monthly-expense-trend': {
type: 'monthly-expense-trend',
- title: 'Monthly Expense Trend',
- description: 'Last 12 months of spend by category',
+ title: w.widget_monthly_expense_trend(),
+ description: w.widget_monthly_expense_trend_description(),
component: MonthlyExpenseTrendWidget,
defaultColSpan: 9,
defaultRowSpan: 8
},
'cost-by-vehicle-leaderboard': {
type: 'cost-by-vehicle-leaderboard',
- title: 'Cost by Vehicle',
- description: 'Which vehicles cost the most to run',
+ title: w.widget_cost_by_vehicle(),
+ description: w.widget_cost_by_vehicle_description(),
component: VehicleLeaderboardWidget,
extraProps: { metric: 'cost' },
defaultColSpan: 6,
@@ -116,32 +117,32 @@ export const WIDGET_REGISTRY: Record = {
},
'fleet-fuel-trend': {
type: 'fleet-fuel-trend',
- title: 'Fleet Fuel Trend',
- description: 'Daily fuel usage across the fleet',
+ title: w.widget_fleet_fuel_trend(),
+ description: w.widget_fleet_fuel_trend_description(),
component: FleetFuelTrendWidget,
defaultColSpan: 9,
defaultRowSpan: 8
},
'fuel-consumption-trend': {
type: 'fuel-consumption-trend',
- title: 'Fuel Consumption Trend',
- description: 'Fuel usage over time, one line per vehicle',
+ title: w.widget_fuel_consumption_trend(),
+ description: w.widget_fuel_consumption_trend_description(),
component: FuelConsumptionTrendWidget,
defaultColSpan: 9,
defaultRowSpan: 8
},
'mileage-overview-trend': {
type: 'mileage-overview-trend',
- title: 'Mileage Overview',
- description: 'Mileage over time, one line per vehicle',
+ title: w.widget_mileage_overview(),
+ description: w.widget_mileage_overview_description(),
component: MileageOverviewWidget,
defaultColSpan: 9,
defaultRowSpan: 8
},
'efficiency-leaderboard': {
type: 'efficiency-leaderboard',
- title: 'Efficiency Leaderboard',
- description: 'Vehicles ranked by fuel efficiency',
+ title: w.widget_efficiency_leaderboard(),
+ description: w.widget_efficiency_leaderboard_description(),
component: VehicleLeaderboardWidget,
extraProps: { metric: 'efficiency' },
defaultColSpan: 6,
@@ -149,8 +150,8 @@ export const WIDGET_REGISTRY: Record = {
},
'pucc-status-donut': {
type: 'pucc-status-donut',
- title: 'Other Compliance Status',
- description: 'Emissions, roadworthiness & registration status across the fleet',
+ title: w.widget_compliance_status(),
+ description: w.widget_compliance_status_description(),
component: StatusDonutWidget,
extraProps: { metric: 'other' },
defaultColSpan: 6,
@@ -158,8 +159,8 @@ export const WIDGET_REGISTRY: Record = {
},
'insurance-status-donut': {
type: 'insurance-status-donut',
- title: 'Insurance Status',
- description: 'Insurance policy status across the fleet',
+ title: w.widget_insurance_status(),
+ description: w.widget_insurance_status_description(),
component: StatusDonutWidget,
extraProps: { metric: 'insurance' },
defaultColSpan: 6,
@@ -167,40 +168,40 @@ export const WIDGET_REGISTRY: Record = {
},
'vehicle-health-distribution': {
type: 'vehicle-health-distribution',
- title: 'Vehicle Health',
- description: 'Overall good/attention/needs-action breakdown',
+ title: w.widget_vehicle_health(),
+ description: w.widget_vehicle_health_description(),
component: VehicleHealthWidget,
defaultColSpan: 6,
defaultRowSpan: 8
},
'upcoming-reminders-list': {
type: 'upcoming-reminders-list',
- title: 'Upcoming Reminders',
- description: 'Reminders coming due soon',
+ title: w.widget_upcoming_reminders(),
+ description: w.widget_upcoming_reminders_description(),
component: UpcomingRemindersWidget,
defaultColSpan: 6,
defaultRowSpan: 8
},
'vehicle-quick-list': {
type: 'vehicle-quick-list',
- title: 'My Vehicles',
- description: 'Quick access to your vehicles',
+ title: w.widget_vehicles_quick_list(),
+ description: w.widget_vehicles_quick_list_description(),
component: VehicleQuickListWidget,
defaultColSpan: 9,
defaultRowSpan: 8
},
'recent-activity-feed': {
type: 'recent-activity-feed',
- title: 'Recent Activity',
- description: 'Latest fuel and maintenance logs across the fleet',
+ title: w.widget_recent_activity(),
+ description: w.widget_recent_activity_description(),
component: RecentActivityWidget,
defaultColSpan: 6,
defaultRowSpan: 8
},
'activity-calendar': {
type: 'activity-calendar',
- title: 'Activity Calendar',
- description: 'Upcoming reminders and past fuel/maintenance activity by date',
+ title: w.widget_activity_calendar(),
+ description: w.widget_activity_calendar_description(),
component: CalendarWidget,
defaultColSpan: 4,
defaultRowSpan: 10
diff --git a/src/lib/components/dashboard/widgets/CalendarWidget.svelte b/src/lib/components/dashboard/widgets/CalendarWidget.svelte
index de5ce4cc..8a611bdc 100644
--- a/src/lib/components/dashboard/widgets/CalendarWidget.svelte
+++ b/src/lib/components/dashboard/widgets/CalendarWidget.svelte
@@ -9,6 +9,7 @@
import Wrench from '@lucide/svelte/icons/wrench';
import Bell from '@lucide/svelte/icons/bell';
import { ACCENT } from '$lib/helper/accent-color.helper';
+ import { widget_calendar_no_activity_or_reminders } from '$lib/paraglide/messages/_index.js';
let { summary, loading }: { summary: DashboardSummary | null; loading: boolean } = $props();
@@ -153,7 +154,7 @@
{formatDateForCalendar(selected)}
{#if selectedEvents.length === 0}
- No activity or reminders on this date.
+ {widget_calendar_no_activity_or_reminders()}
{:else}
{#each selectedEvents as event (event.id)}
diff --git a/src/lib/components/dashboard/widgets/FuelConsumptionTrendWidget.svelte b/src/lib/components/dashboard/widgets/FuelConsumptionTrendWidget.svelte
index 2fee81bd..fc2a9bdb 100644
--- a/src/lib/components/dashboard/widgets/FuelConsumptionTrendWidget.svelte
+++ b/src/lib/components/dashboard/widgets/FuelConsumptionTrendWidget.svelte
@@ -4,6 +4,7 @@
import { chartStore } from '$stores/chart.svelte';
import { fuelLogStore } from '$stores/fuel-log.svelte';
import { vehicleStore } from '$stores/vehicle.svelte';
+ import { widget_fuel_consumption_trend } from '$lib/paraglide/messages/_index.js';
// The dashboard doesn't pre-populate fuelLogStore (unlike the fuel page's
// FuelLogList) — fetch it fleet-wide here; in-flight requests are shared,
@@ -24,7 +25,7 @@
`${value.toFixed(1)} L`}
xFormatter={(v: Date) =>
diff --git a/src/lib/components/dashboard/widgets/MileageOverviewWidget.svelte b/src/lib/components/dashboard/widgets/MileageOverviewWidget.svelte
index bbe5d082..ecd5474b 100644
--- a/src/lib/components/dashboard/widgets/MileageOverviewWidget.svelte
+++ b/src/lib/components/dashboard/widgets/MileageOverviewWidget.svelte
@@ -5,6 +5,7 @@
import { fuelLogStore } from '$stores/fuel-log.svelte';
import { vehicleStore } from '$stores/vehicle.svelte';
import { formatMileage } from '$lib/helper/format.helper';
+ import { widget_mileage_overview } from '$lib/paraglide/messages/_index.js';
// The dashboard doesn't pre-populate fuelLogStore (unlike the fuel page's
// FuelLogList) — fetch it fleet-wide here; in-flight requests are shared,
@@ -25,7 +26,7 @@
formatMileage(value, series.fuelType)}
xFormatter={(v: Date) =>
diff --git a/src/lib/components/dashboard/widgets/UpcomingRemindersWidget.svelte b/src/lib/components/dashboard/widgets/UpcomingRemindersWidget.svelte
index bc0f535c..10a98bbe 100644
--- a/src/lib/components/dashboard/widgets/UpcomingRemindersWidget.svelte
+++ b/src/lib/components/dashboard/widgets/UpcomingRemindersWidget.svelte
@@ -3,6 +3,7 @@
import Bell from '@lucide/svelte/icons/bell';
import type { DashboardSummary } from '$lib/domain/dashboard';
import { ACCENT } from '$lib/helper/accent-color.helper';
+ import { widget_no_upcoming_reminders } from '$lib/paraglide/messages/_index.js';
let { summary, loading }: { summary: DashboardSummary | null; loading: boolean } = $props();
@@ -44,6 +45,6 @@
Loading reminders...
{:else}
- No upcoming reminders
+ {widget_no_upcoming_reminders()}
{/if}
diff --git a/src/lib/components/dashboard/widgets/VehicleQuickListWidget.svelte b/src/lib/components/dashboard/widgets/VehicleQuickListWidget.svelte
index ed851aff..68848420 100644
--- a/src/lib/components/dashboard/widgets/VehicleQuickListWidget.svelte
+++ b/src/lib/components/dashboard/widgets/VehicleQuickListWidget.svelte
@@ -2,6 +2,7 @@
import VehicleListItem from '$feature/vehicle/VehicleListItem.svelte';
import { vehicleStore } from '$stores/vehicle.svelte';
import { goto } from '$app/navigation';
+ import { widget_no_vehicles_yet } from '$lib/paraglide/messages/_index.js';
{#if vehicleStore.vehicles && vehicleStore.vehicles.length > 0}
@@ -18,6 +19,6 @@
{:else}
- No vehicles yet
+ {widget_no_vehicles_yet()}
{/if}
diff --git a/src/lib/components/feature/dashboard/AddWidgetPanel.svelte b/src/lib/components/feature/dashboard/AddWidgetPanel.svelte
index 56a38773..9ccf9e4a 100644
--- a/src/lib/components/feature/dashboard/AddWidgetPanel.svelte
+++ b/src/lib/components/feature/dashboard/AddWidgetPanel.svelte
@@ -4,6 +4,7 @@
import { sheetStore } from '$stores/sheet.svelte';
import CirclePlus from '@lucide/svelte/icons/circle-plus';
import type { WidgetType } from '$lib/domain/dashboard';
+ import { all_widgets_used } from '$lib/paraglide/messages/_index.js';
const availableWidgets = $derived(
dashboardLayoutStore.availableWidgetTypes.map((type) => WIDGET_REGISTRY[type])
@@ -19,7 +20,7 @@
{#if availableWidgets.length === 0}
- All available widgets are already on your dashboard.
+ {all_widgets_used()}
{:else}
{#each availableWidgets as widget (widget.type)}
diff --git a/src/lib/components/layout/AppSidebar.svelte b/src/lib/components/layout/AppSidebar.svelte
index bc73e377..d2ceccb4 100644
--- a/src/lib/components/layout/AppSidebar.svelte
+++ b/src/lib/components/layout/AppSidebar.svelte
@@ -47,50 +47,50 @@
const NAV_ITEMS: NavItem[] = [
{
- label: 'Dashboard',
+ label: m.nav_dashboard(),
href: '/dashboard',
icon: LayoutDashboard,
- group: 'Overview'
+ group: m.nav_overview()
},
{
- label: 'Garage',
+ label: m.nav_garage(),
href: '/garage',
icon: Warehouse,
- group: 'Overview'
+ group: m.nav_overview()
},
{
label: m.nav_fuel_logs(),
href: '/fuel',
icon: Fuel,
featureKey: 'featureFuelLog',
- group: 'Logs'
+ group: m.nav_logs()
},
{
label: m.nav_maintenance(),
href: '/maintenance',
icon: Wrench,
featureKey: 'featureMaintenance',
- group: 'Logs'
+ group: m.nav_logs()
},
{
label: m.nav_reminders(),
href: '/reminders',
icon: Bell,
featureKey: 'featureReminders',
- group: 'Logs'
+ group: m.nav_logs()
},
{
label: m.nav_compliance(),
href: '/compliance',
icon: Shield,
featureKey: 'featureCompliance',
- group: 'Logs'
+ group: m.nav_logs()
},
{
- label: 'Reports',
+ label: m.nav_reports(),
href: '/reports',
icon: BarChart3,
- group: 'Insights'
+ group: m.nav_insights()
}
];
diff --git a/src/routes/(app)/dashboard/+page.svelte b/src/routes/(app)/dashboard/+page.svelte
index e84be8fc..a51c8f9d 100644
--- a/src/routes/(app)/dashboard/+page.svelte
+++ b/src/routes/(app)/dashboard/+page.svelte
@@ -20,6 +20,20 @@
import DeleteConfirmation from '$appui/DeleteConfirmation.svelte';
import { goto } from '$app/navigation';
import * as m from '$lib/paraglide/messages';
+ import {
+ dashboard_add_widget,
+ dashboard_title,
+ dashboard_good_morning,
+ dashboard_good_afternoon,
+ dashboard_good_evening,
+ dashboard_reset_to_default,
+ dashboard_reset_confirm_title,
+ dashboard_reset_confirm_message,
+ dashboard_reset_confirm_reset,
+ dashboard_cta_heading,
+ dashboard_cta_description,
+ dashboard_cta_button_label
+ } from '$lib/paraglide/messages/_index.js';
let resetDialogOpen = $state(false);
@@ -34,18 +48,26 @@
const greeting = $derived.by(() => {
if (!authStore.user?.username) return 'Welcome';
const hour = new Date().getHours();
- const timeGreeting = hour < 12 ? 'Good morning' : hour < 18 ? 'Good afternoon' : 'Good evening';
+ const timeGreeting =
+ hour < 12
+ ? dashboard_good_morning()
+ : hour < 18
+ ? dashboard_good_afternoon()
+ : dashboard_good_evening();
return `${timeGreeting}, ${authStore.user.username}`;
});
-
+
-