mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-29 07:54:44 +00:00
refactor(db): replace sqlc with handwritten pgx repos
- Finish Paddle-to-Stripe billing migration; drop paddle/stripe libs - Renumber migrations; add 00012 memberships+manage_token, 00013 location_type_capacity - Add tests: admin, auth, bookings customer service - Remove graphify-out artifacts and stale env files Authored By: TDvorak <[email protected]> Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
2039669e2c
commit
f2f7439050
93 files changed
+6987
-69060
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import { Show, createEffect, createResource, createSignal } from "solid-js";
|
||||
import { apiClient } from "../../lib/api-client";
|
||||
import { Input } from "../../components/ui/input";
|
||||
import { Textarea } from "../../components/ui/textarea";
|
||||
@@ -16,6 +16,26 @@ function SettingsPage() {
|
||||
const [emailBody, setEmailBody] = createSignal("");
|
||||
const [emailSaving, setEmailSaving] = createSignal(false);
|
||||
|
||||
const [emailTemplates, { refetch: refetchTemplates }] = createResource(
|
||||
() => data.token(),
|
||||
async (bearer) => {
|
||||
if (!bearer || bearer.startsWith("demo.")) return [];
|
||||
try {
|
||||
const response = await (apiClient as any).GET("/v1/tenants/email-templates", { headers: { Authorization: `Bearer ${bearer}` } });
|
||||
return (response.data?.templates as any[]) ?? [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Prefill the editor from the stored template whenever the type changes.
|
||||
createEffect(() => {
|
||||
const tpl = (emailTemplates() ?? []).find((t: any) => t.type === activeEmailType());
|
||||
setEmailSubject(tpl?.subject ?? "");
|
||||
setEmailBody(tpl?.bodyText ?? tpl?.bodyHtml ?? "");
|
||||
});
|
||||
|
||||
const presetColors = [
|
||||
{ name: data.i18n.locale() === "cs" ? "Hnědá" : "Terracotta", color: "#c25e3a" },
|
||||
{ name: data.i18n.locale() === "cs" ? "Zelená" : "Sage", color: "#5a7c5a" },
|
||||
@@ -68,7 +88,7 @@ function SettingsPage() {
|
||||
<div class="w-10 h-10 rounded-full flex items-center justify-center text-canvas font-bold" style={{ background: brandColor() }}>B</div>
|
||||
<div>
|
||||
<p class="font-semibold text-ink">Bookra</p>
|
||||
<p class="text-xs text-ink-muted">{data.i18n.locale() === "cs" ? "Rezervujte si termin" : "Book an appointment"}</p>
|
||||
<p class="text-xs text-ink-muted">{data.i18n.locale() === "cs" ? "Rezervujte si termín" : "Book an appointment"}</p>
|
||||
</div>
|
||||
</div>
|
||||
<button class="w-full py-2.5 rounded-lg text-canvas font-medium text-sm" style={{ background: brandColor() }}>{data.i18n.locale() === "cs" ? "Rezervovat" : "Book Now"}</button>
|
||||
@@ -109,7 +129,8 @@ function SettingsPage() {
|
||||
if (!bearer || bearer.startsWith("demo.")) { data.setDemoNotice(data.i18n.locale() === "cs" ? "V demo režimu nelze ukládat." : "Cannot save in demo mode."); return; }
|
||||
setEmailSaving(true);
|
||||
try {
|
||||
await (apiClient as any).PUT("/v1/tenants/email-template", { headers: { Authorization: `Bearer ${bearer}` }, body: { type: activeEmailType(), subject: emailSubject(), body: emailBody() } });
|
||||
await (apiClient as any).PUT("/v1/tenants/email-template", { headers: { Authorization: `Bearer ${bearer}` }, body: { type: activeEmailType(), subject: emailSubject(), body: emailBody(), isEnabled: true } });
|
||||
void refetchTemplates();
|
||||
data.setDemoNotice(data.i18n.locale() === "cs" ? "Šablona uložena." : "Template saved.");
|
||||
} catch { data.setDemoNotice(data.i18n.locale() === "cs" ? "Chyba při ukládání." : "Save failed."); }
|
||||
finally { setEmailSaving(false); }
|
||||
|
||||
Reference in new issue
Block a user