i18n: add Paraglide messages for all events pages (EN + ET)

This commit is contained in:
AlacrisDevs
2026-02-07 10:16:13 +02:00
parent 36496e8cdb
commit fe6ec6e0af
6 changed files with 232 additions and 94 deletions

View File

@@ -6,6 +6,7 @@
import type { Database } from "$lib/supabase/types";
import { toasts } from "$lib/stores/ui";
import type { Event, EventMember } from "$lib/api/events";
import * as m from "$lib/paraglide/messages";
interface Props {
data: {
@@ -63,74 +64,74 @@
`/${data.org.slug}/events/${data.event.slug}`,
);
const statusOptions = [
{ value: "planning", label: "Planning", icon: "edit_note", color: "text-amber-400" },
{ value: "active", label: "Active", icon: "play_circle", color: "text-emerald-400" },
{ value: "completed", label: "Completed", icon: "check_circle", color: "text-blue-400" },
{ value: "archived", label: "Archived", icon: "archive", color: "text-light/40" },
];
const statusOptions = $derived([
{ value: "planning", label: m.events_status_planning(), icon: "edit_note", color: "text-amber-400" },
{ value: "active", label: m.events_status_active(), icon: "play_circle", color: "text-emerald-400" },
{ value: "completed", label: m.events_status_completed(), icon: "check_circle", color: "text-blue-400" },
{ value: "archived", label: m.events_status_archived(), icon: "archive", color: "text-light/40" },
]);
const moduleCards = $derived([
{
href: `${basePath}/tasks`,
label: "Tasks",
label: m.events_mod_tasks(),
icon: "task_alt",
description: "Manage tasks, milestones, and progress",
description: m.events_mod_tasks_desc(),
color: "text-emerald-400",
bg: "bg-emerald-400/10",
},
{
href: `${basePath}/files`,
label: "Files",
label: m.events_mod_files(),
icon: "folder",
description: "Documents, contracts, and media",
description: m.events_mod_files_desc(),
color: "text-blue-400",
bg: "bg-blue-400/10",
},
{
href: `${basePath}/schedule`,
label: "Schedule",
label: m.events_mod_schedule(),
icon: "calendar_today",
description: "Event timeline and program",
description: m.events_mod_schedule_desc(),
color: "text-purple-400",
bg: "bg-purple-400/10",
},
{
href: `${basePath}/budget`,
label: "Budget",
label: m.events_mod_budget(),
icon: "account_balance_wallet",
description: "Income, expenses, and tracking",
description: m.events_mod_budget_desc(),
color: "text-amber-400",
bg: "bg-amber-400/10",
},
{
href: `${basePath}/guests`,
label: "Guests",
label: m.events_mod_guests(),
icon: "groups",
description: "Guest list and registration",
description: m.events_mod_guests_desc(),
color: "text-pink-400",
bg: "bg-pink-400/10",
},
{
href: `${basePath}/team`,
label: "Team",
label: m.events_mod_team(),
icon: "badge",
description: "Team members and shift scheduling",
description: m.events_mod_team_desc(),
color: "text-teal-400",
bg: "bg-teal-400/10",
},
{
href: `${basePath}/sponsors`,
label: "Sponsors",
label: m.events_mod_sponsors(),
icon: "handshake",
description: "Sponsors, partners, and deliverables",
description: m.events_mod_sponsors_desc(),
color: "text-orange-400",
bg: "bg-orange-400/10",
},
]);
function formatDate(dateStr: string | null): string {
if (!dateStr) return "Not set";
if (!dateStr) return m.events_not_set();
return new Date(dateStr).toLocaleDateString(undefined, {
weekday: "short",
month: "long",
@@ -146,10 +147,10 @@
const diff = Math.ceil(
(start.getTime() - now.getTime()) / (1000 * 60 * 60 * 24),
);
if (diff < 0) return `${Math.abs(diff)} days ago`;
if (diff === 0) return "Today!";
if (diff === 1) return "Tomorrow";
return `In ${diff} days`;
if (diff < 0) return m.events_days_ago({ count: String(Math.abs(diff)) });
if (diff === 0) return m.events_today();
if (diff === 1) return m.events_tomorrow();
return m.events_in_days({ count: String(diff) });
}
async function handleSave() {
@@ -171,7 +172,7 @@
if (error) throw error;
toasts.success("Event updated");
toasts.success(m.events_updated());
editing = false;
// Refresh the page data
goto(`/${data.org.slug}/events/${data.event.slug}`, {
@@ -194,7 +195,7 @@
if (error) throw error;
toasts.success("Event deleted");
toasts.success(m.events_deleted());
goto(`/${data.org.slug}/events`);
} catch (e: any) {
toasts.error(e.message || "Failed to delete event");
@@ -299,7 +300,7 @@
class="px-3 py-1.5 text-body-sm text-light/60 hover:text-white transition-colors"
onclick={() => (editing = false)}
>
Cancel
{m.btn_cancel()}
</button>
<button
type="button"
@@ -307,13 +308,13 @@
disabled={saving}
onclick={handleSave}
>
{saving ? "Saving..." : "Save"}
{saving ? m.events_saving() : m.btn_save()}
</button>
{:else}
<button
type="button"
class="p-2 text-light/40 hover:text-white transition-colors rounded-lg hover:bg-dark/50"
title="Edit event"
title={m.btn_edit()}
onclick={() => (editing = true)}
>
<span
@@ -325,7 +326,7 @@
<button
type="button"
class="p-2 text-light/40 hover:text-error transition-colors rounded-lg hover:bg-error/10"
title="Delete event"
title={m.btn_delete()}
onclick={() => (showDeleteConfirm = true)}
>
<span
@@ -365,13 +366,13 @@
<input
type="text"
bind:value={editVenueName}
placeholder="Venue name"
placeholder={m.events_form_venue_placeholder()}
class="bg-dark border border-light/10 rounded-xl px-3 py-2 text-body-sm text-white placeholder:text-light/30 focus:outline-none focus:border-primary"
/>
<input
type="text"
bind:value={editVenueAddress}
placeholder="Venue address"
placeholder={m.events_form_venue_address_placeholder()}
class="bg-dark border border-light/10 rounded-xl px-3 py-2 text-body-sm text-white placeholder:text-light/30 focus:outline-none focus:border-primary"
/>
</div>
@@ -388,7 +389,7 @@
{/if}
<!-- Module Cards Grid -->
<h2 class="text-h3 font-heading text-white mb-4">Modules</h2>
<h2 class="text-h3 font-heading text-white mb-4">{m.events_modules()}</h2>
<div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3"
>
@@ -421,7 +422,7 @@
<!-- Info Card -->
<div class="bg-dark/30 border border-light/5 rounded-xl p-5">
<h3 class="text-body font-heading text-white mb-3">
Event Details
{m.events_details()}
</h3>
<div class="flex flex-col gap-2.5">
<div class="flex items-center gap-3">
@@ -432,7 +433,7 @@
>
<div>
<p class="text-[11px] text-light/40">
Start Date
{m.events_start_date()}
</p>
<p class="text-body-sm text-white">
{formatDate(data.event.start_date)}
@@ -446,7 +447,7 @@
>event</span
>
<div>
<p class="text-[11px] text-light/40">End Date</p>
<p class="text-[11px] text-light/40">{m.events_end_date()}</p>
<p class="text-body-sm text-white">
{formatDate(data.event.end_date)}
</p>
@@ -460,7 +461,7 @@
>location_on</span
>
<div>
<p class="text-[11px] text-light/40">Venue</p>
<p class="text-[11px] text-light/40">{m.events_venue()}</p>
<p class="text-body-sm text-white">
{data.event.venue_name}
</p>
@@ -479,12 +480,12 @@
<div class="bg-dark/30 border border-light/5 rounded-xl p-5">
<div class="flex items-center justify-between mb-3">
<h3 class="text-body font-heading text-white">
Team ({data.eventMembers.length})
{m.events_team_count({ count: String(data.eventMembers.length) })}
</h3>
<a
href="{basePath}/team"
class="text-[12px] text-primary hover:underline"
>Manage</a
>{m.events_team_manage()}</a
>
</div>
<div class="flex flex-col gap-2">
@@ -518,12 +519,12 @@
href="{basePath}/team"
class="text-body-sm text-primary hover:underline text-center pt-1"
>
+{data.eventMembers.length - 6} more
{m.events_more_members({ count: String(data.eventMembers.length - 6) })}
</a>
{/if}
{#if data.eventMembers.length === 0}
<p class="text-body-sm text-light/30 text-center py-4">
No team members assigned yet
{m.events_team_empty()}
</p>
{/if}
</div>
@@ -543,17 +544,14 @@
e.target === e.currentTarget && (showDeleteConfirm = false)}
role="dialog"
aria-modal="true"
aria-label="Delete Event"
aria-label={m.events_delete_title()}
>
<div
class="bg-night rounded-2xl w-full max-w-sm shadow-2xl border border-light/10 p-6"
>
<h2 class="text-h3 font-heading text-white mb-2">Delete Event?</h2>
<h2 class="text-h3 font-heading text-white mb-2">{m.events_delete_title()}</h2>
<p class="text-body-sm text-light/50 mb-6">
This will permanently delete <strong class="text-white"
>{data.event.name}</strong
>
and all its data. This action cannot be undone.
{m.events_delete_desc({ name: data.event.name })}
</p>
<div class="flex items-center justify-end gap-3">
<button
@@ -561,7 +559,7 @@
class="px-4 py-2 text-body-sm text-light/60 hover:text-white transition-colors"
onclick={() => (showDeleteConfirm = false)}
>
Cancel
{m.btn_cancel()}
</button>
<button
type="button"
@@ -569,7 +567,7 @@
disabled={deleting}
onclick={handleDelete}
>
{deleting ? "Deleting..." : "Delete Event"}
{deleting ? m.events_deleting() : m.events_delete_confirm()}
</button>
</div>
</div>