feat(i18n): convert Settings calendar section to t() (Batch E)

This commit is contained in:
iamdoubz committed 2026-07-12 12:30:51 -05:00
1 parent f1683af01c
commit 802e30e9c6
1 file changed
+61 -50
+61 -50
View File
@@ -1125,46 +1125,54 @@
</section> </section>
{:else if section === "calendar"} {:else if section === "calendar"}
<section> <section>
<h3>Calendar &amp; Outlook .pst</h3> <h3>{t("settings.calendar.title")}</h3>
<p class="muted"> <p class="muted">
Import events and attendees from a local Outlook <code>.pst</code> backup — read-only, nothing {t("settings.calendar.intro_1")} <code>.pst</code>
is written back to the file. Nothing leaves this device. {t("settings.calendar.intro_2")}
</p> </p>
<div class="grid"> <div class="grid">
<label class="wide" <label class="wide"
>.pst file >{t("settings.calendar.pst_file")}
<div class="row"> <div class="row">
<input class="grow" bind:value={pstPath} placeholder="No file selected" readonly /> <input
<button onclick={pickPstFile}>Browse…</button> class="grow"
bind:value={pstPath}
placeholder={t("settings.calendar.no_file")}
readonly
/>
<button onclick={pickPstFile}>{t("settings.calendar.browse")}</button>
</div> </div>
</label> </label>
<label <label
>Password <em>(rarely needed)</em> >{t("settings.calendar.password")} <em>({t("settings.calendar.password_note")})</em>
<input type="password" bind:value={pstPassword} placeholder="optional" /> <input
type="password"
bind:value={pstPassword}
placeholder={t("settings.calendar.optional")}
/>
</label> </label>
<label <label
>Import range >{t("settings.calendar.import_range")}
<select value={importRange} onchange={onImportRangeChange}> <select value={importRange} onchange={onImportRangeChange}>
<option value="30">Last 30 days</option> <option value="30">{t("settings.calendar.range_30")}</option>
<option value="90">Last 90 days</option> <option value="90">{t("settings.calendar.range_90")}</option>
<option value="180">Last 6 months</option> <option value="180">{t("settings.calendar.range_180")}</option>
<option value="365">Last 1 year</option> <option value="365">{t("settings.calendar.range_365")}</option>
<option value="all">All time</option> <option value="all">{t("settings.calendar.range_all")}</option>
</select> </select>
</label> </label>
</div> </div>
<p class="muted small"> <p class="muted small">{t("settings.calendar.range_hint")}</p>
A long-lived mailbox can hold years of recurring/holiday entries — narrowing the range
keeps the imported calendar to what's actually relevant. Applies to both this Import
button and automatic re-import on launch.
</p>
<div class="actions"> <div class="actions">
<button class="primary" onclick={doImportPst} disabled={!pstPath || calendar.importing}> <button class="primary" onclick={doImportPst} disabled={!pstPath || calendar.importing}>
{calendar.importing ? "Importing…" : "Import"} {calendar.importing ? t("settings.calendar.importing") : t("settings.calendar.import")}
</button> </button>
{#if calendar.importProgress} {#if calendar.importProgress}
<span class="muted" <span class="muted"
>{calendar.importProgress.processed}/{calendar.importProgress.total} events</span >{t("settings.calendar.import_progress", {
processed: calendar.importProgress.processed,
total: calendar.importProgress.total,
})}</span
> >
{/if} {/if}
</div> </div>
@@ -1174,31 +1182,24 @@
checked={settings.settings.pst_auto_sync} checked={settings.settings.pst_auto_sync}
onchange={onToggleAutoSync} onchange={onToggleAutoSync}
/> />
<span>Re-import this file automatically on launch</span> <span>{t("settings.calendar.auto_reimport")}</span>
</label> </label>
<p class="muted small"> <p class="muted small">{t("settings.calendar.auto_reimport_hint")}</p>
Runs once at startup, not on a timer — re-import is safe to repeat (existing events are
matched and updated, not duplicated).
</p>
{#if calendar.importError} {#if calendar.importError}
<p class="error"> <p class="error">
Import failed: {calendar.importError} — the file itself is untouched; check the path and try {t("settings.calendar.import_failed", { error: calendar.importError })}
again.
</p> </p>
{/if} {/if}
<h4>Clean up</h4> <h4>{t("settings.calendar.cleanup_title")}</h4>
<p class="muted small"> <p class="muted small">{t("settings.calendar.cleanup_hint")}</p>
Events already attached to a recorded meeting are always kept, no matter which option
below is picked.
</p>
<div class="actions"> <div class="actions">
<select bind:value={cleanupThreshold} disabled={cleanupRunning}> <select bind:value={cleanupThreshold} disabled={cleanupRunning}>
<option value="30">Older than 30 days</option> <option value="30">{t("settings.calendar.cleanup_30")}</option>
<option value="90">Older than 90 days</option> <option value="90">{t("settings.calendar.cleanup_90")}</option>
<option value="180">Older than 6 months</option> <option value="180">{t("settings.calendar.cleanup_180")}</option>
<option value="365">Older than 1 year</option> <option value="365">{t("settings.calendar.cleanup_365")}</option>
<option value="all">Delete all</option> <option value="all">{t("settings.calendar.cleanup_all")}</option>
</select> </select>
<button <button
class="icon-btn danger" class="icon-btn danger"
@@ -1206,41 +1207,51 @@
disabled={cleanupRunning || calendar.events.length === 0} disabled={cleanupRunning || calendar.events.length === 0}
> >
<Trash2 size={13} aria-hidden="true" /> <Trash2 size={13} aria-hidden="true" />
{cleanupRunning ? "Cleaning up…" : "Clean up calendar"} {cleanupRunning ? t("settings.calendar.cleaning") : t("settings.calendar.cleanup_btn")}
</button> </button>
</div> </div>
{#if cleanupResult} {#if cleanupResult}
<p class="muted small"> <p class="muted small">
Deleted {cleanupResult.deleted}{cleanupResult.protected {t("settings.calendar.cleanup_result", {
? `, kept ${cleanupResult.protected} (linked to a meeting)` deleted: cleanupResult.deleted,
: ""}. extra: cleanupResult.protected
? t("settings.calendar.cleanup_kept", { n: cleanupResult.protected })
: "",
})}
</p> </p>
{/if} {/if}
{#if cleanupError} {#if cleanupError}
<p class="error">Clean up failed: {cleanupError}</p> <p class="error">{t("settings.calendar.cleanup_failed", { error: cleanupError })}</p>
{/if} {/if}
<h4>Imported events</h4> <h4>{t("settings.calendar.imported_events")}</h4>
{#if calendar.events.length === 0} {#if calendar.events.length === 0}
<p class="muted">No events imported yet.</p> <p class="muted">{t("settings.calendar.no_events")}</p>
{:else} {:else}
<div class="grid"> <div class="grid">
<label class="wide" <label class="wide"
>Search title >{t("settings.calendar.search_title")}
<input type="text" bind:value={eventTitleFilter} placeholder="Meeting name…" /> <input
type="text"
bind:value={eventTitleFilter}
placeholder={t("settings.calendar.search_placeholder")}
/>
</label> </label>
<label <label
>Date >{t("settings.calendar.date_label")}
<input type="date" bind:value={eventDateFilter} /> <input type="date" bind:value={eventDateFilter} />
</label> </label>
</div> </div>
<p class="muted"> <p class="muted">
{filteredEvents.length} of {calendar.events.length} events {t("settings.calendar.events_count", {
shown: filteredEvents.length,
total: calendar.events.length,
})}
</p> </p>
<ul class="events"> <ul class="events">
{#each filteredEvents as ev (ev.id)} {#each filteredEvents as ev (ev.id)}
<li> <li>
<span class="name">{ev.subject ?? "(untitled)"}</span> <span class="name">{ev.subject ?? t("settings.calendar.untitled")}</span>
<span class="muted">{formatEventDate(ev.starts_at)}</span> <span class="muted">{formatEventDate(ev.starts_at)}</span>
{#if ev.organizer}<span class="muted">· {ev.organizer}</span>{/if} {#if ev.organizer}<span class="muted">· {ev.organizer}</span>{/if}
</li> </li>