Files
flxn-app/src/features/settings/components/notifications-section.tsx
T
kyle f6faf97cdf
CI/CD Pipeline / Build and Push PocketBase Docker Image (push) Successful in 10s
CI/CD Pipeline / i18n Catalog Check (push) Successful in 43s
CI/CD Pipeline / Build and Push App Docker Image (push) Successful in 2m14s
CI/CD Pipeline / Deploy to Kubernetes (push) Successful in 8m29s
develpoer role
2026-08-30 12:36:28 -05:00

121 lines
3.6 KiB
TypeScript

import { useState } from "react";
import { Box, Title, Stack, Switch, Button, Text, Group } from "@mantine/core";
import { Trans, useLingui } from "@lingui/react/macro";
import { useWebPush } from "@/hooks/use-web-push";
import { useAuth } from "@/contexts/auth-context";
import { useIsDeveloper } from "@/features/core/hooks/use-is-developer";
import { updateUserTelemetryAlerts } from "@/features/settings/server";
import toast from "@/lib/sonner";
const TelemetryAlertsSwitch = () => {
const { t } = useLingui();
const { metadata, set } = useAuth();
const [saving, setSaving] = useState(false);
const handleToggle = async (checked: boolean) => {
setSaving(true);
try {
const result = await updateUserTelemetryAlerts({ data: checked });
if (result?.metadata) {
set({ metadata: result.metadata });
}
} catch {
toast.error(t`Couldn't update telemetry alerts`);
} finally {
setSaving(false);
}
};
return (
<Switch
checked={metadata?.telemetryAlerts === true}
onChange={(e) => handleToggle(e.currentTarget.checked)}
disabled={saving}
label={t`Telemetry alerts`}
description={t`Error spikes and failing functions, pushed to this account`}
/>
);
};
export function NotificationsSection() {
const { supported, configured, permission, subscribed, busy, enable, disable, sendTest } =
useWebPush();
const isDeveloper = useIsDeveloper();
const { t } = useLingui();
if (!supported || !configured) {
return (
<Box
px="md"
py="sm"
style={{ borderBottom: "1px solid var(--mantine-color-default-border)" }}
>
<Title order={3}><Trans>Notifications</Trans></Title>
<Text size="sm" c="dimmed" mt="xs">
{supported
? <Trans>Notifications aren't available right now.</Trans>
: <Trans>This device doesn't support push notifications. On iOS, install the app to your Home Screen first.</Trans>}
</Text>
</Box>
);
}
const handleToggle = async (checked: boolean) => {
if (checked) {
const ok = await enable();
if (ok) {
toast.success(t`Notifications enabled on this device`);
} else if (permission === "denied") {
toast.error(
t`Notifications are blocked. Enable them in your browser settings.`
);
} else {
toast.error(t`Couldn't enable notifications`);
}
} else {
const ok = await disable();
if (ok) toast.success(t`Notifications disabled on this device`);
else toast.error(t`Couldn't disable notifications`);
}
};
const handleTest = async () => {
const ok = await sendTest();
if (ok) toast.success(t`Test notification sent`);
else toast.error(t`Couldn't send test notification`);
};
return (
<Box
px="md"
py="sm"
style={{ borderBottom: "1px solid var(--mantine-color-default-border)" }}
>
<Title order={3}><Trans>Notifications</Trans></Title>
<Stack mt="xs" gap="sm">
<Switch
checked={subscribed}
onChange={(e) => handleToggle(e.currentTarget.checked)}
disabled={busy}
label={t`Enable notifications on this device`}
/>
{subscribed && isDeveloper && <TelemetryAlertsSwitch />}
{subscribed && (
<Group>
<Button
variant="light"
size="xs"
onClick={handleTest}
loading={busy}
>
<Trans>Send test notification</Trans>
</Button>
</Group>
)}
</Stack>
</Box>
);
}
export default NotificationsSection;