fix(notifications): drop per-category descriptions, capitalise "Mobil Bildirim" #107
@@ -37,12 +37,11 @@ export class EmailPreferencesController {
|
||||
@Get()
|
||||
async list(
|
||||
@CurrentUser() user: { id: string },
|
||||
): Promise<Array<{ category: string; label: string; description: string; optedOut: boolean }>> {
|
||||
): Promise<Array<{ category: string; label: string; optedOut: boolean }>> {
|
||||
return Promise.all(
|
||||
NOTIFICATION_CATEGORIES.map(async (cat) => ({
|
||||
category: cat.key,
|
||||
label: cat.label,
|
||||
description: cat.description,
|
||||
optedOut: await this.preferences.getCategoryState(user.id, cat.key),
|
||||
})),
|
||||
);
|
||||
|
||||
@@ -35,13 +35,14 @@ export const OPTIONAL_WORKFLOWS = new Set<string>([
|
||||
*
|
||||
* Order matters — that's the order the settings UI renders. Keep
|
||||
* `email_marketing` first since it's the bigger lever today.
|
||||
*
|
||||
* No per-category description string — the row title speaks for itself in
|
||||
* the settings UI, the auth/payment caveat lives in a static footer.
|
||||
*/
|
||||
export const NOTIFICATION_CATEGORIES = [
|
||||
{
|
||||
key: "email_marketing" as const,
|
||||
label: "E-posta bildirimleri",
|
||||
description:
|
||||
"Hoş geldin, deneme bitişi, davet hatırlatması, ödül ve geri kazanma mailleri. Hesap güvenliği ve ödeme bildirimleri her zaman gelir.",
|
||||
workflows: [
|
||||
"welcome",
|
||||
"trial-ending",
|
||||
@@ -53,9 +54,7 @@ export const NOTIFICATION_CATEGORIES = [
|
||||
},
|
||||
{
|
||||
key: "mobile_push" as const,
|
||||
label: "Mobil bildirim",
|
||||
description:
|
||||
"Mobil uygulama push bildirimleri. Mobil uygulama yayınlandığında bu tercih kullanılır.",
|
||||
label: "Mobil Bildirim",
|
||||
workflows: ["mobile_push"] as const,
|
||||
},
|
||||
] as const;
|
||||
|
||||
@@ -60,32 +60,20 @@ const TAB_ITEMS = [
|
||||
* NOTIFICATION_CATEGORIES`. We render two switches, not six, because users
|
||||
* care about "e-mail vs mobile" not "did the day-3 referral mail fire".
|
||||
*
|
||||
* The API also returns these (`label`, `description`) so the server is the
|
||||
* source of truth for copy; the static fallback here just avoids a flash of
|
||||
* untitled rows before the GET completes.
|
||||
* The API also returns each category's label so the server is the source of
|
||||
* truth for copy; the static fallback below just avoids a flash of untitled
|
||||
* rows before the GET completes.
|
||||
*/
|
||||
type NotificationCategoryKey = "email_marketing" | "mobile_push";
|
||||
|
||||
const FALLBACK_CATEGORY_COPY: Record<
|
||||
NotificationCategoryKey,
|
||||
{ label: string; description: string }
|
||||
> = {
|
||||
email_marketing: {
|
||||
label: "E-posta bildirimleri",
|
||||
description:
|
||||
"Hoş geldin, deneme bitişi, davet hatırlatması, ödül ve geri kazanma mailleri. Hesap güvenliği ve ödeme bildirimleri her zaman gelir.",
|
||||
},
|
||||
mobile_push: {
|
||||
label: "Mobil bildirim",
|
||||
description:
|
||||
"Mobil uygulama push bildirimleri. Mobil uygulama yayınlandığında bu tercih kullanılır.",
|
||||
},
|
||||
const FALLBACK_CATEGORY_LABEL: Record<NotificationCategoryKey, string> = {
|
||||
email_marketing: "E-posta bildirimleri",
|
||||
mobile_push: "Mobil Bildirim",
|
||||
};
|
||||
|
||||
interface NotificationPref {
|
||||
category: NotificationCategoryKey;
|
||||
label: string;
|
||||
description: string;
|
||||
optedOut: boolean;
|
||||
}
|
||||
|
||||
@@ -745,20 +733,15 @@ function NotificationsCard() {
|
||||
if (isLoading) {
|
||||
return <Skeleton key={key} className="h-20 w-full" />;
|
||||
}
|
||||
const fallback = FALLBACK_CATEGORY_COPY[key];
|
||||
const label = row?.label ?? fallback.label;
|
||||
const description = row?.description ?? fallback.description;
|
||||
const label = row?.label ?? FALLBACK_CATEGORY_LABEL[key];
|
||||
const optedOut = row?.optedOut ?? false;
|
||||
const isPending = pending.has(key);
|
||||
return (
|
||||
<div
|
||||
key={key}
|
||||
className="flex items-start justify-between gap-4 rounded-lg border p-4"
|
||||
className="flex items-center justify-between gap-4 rounded-lg border p-4"
|
||||
>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="text-sm font-medium">{label}</p>
|
||||
<p className="mt-1 text-sm text-muted-foreground">{description}</p>
|
||||
</div>
|
||||
<p className="min-w-0 flex-1 text-sm font-medium">{label}</p>
|
||||
<Button
|
||||
type="button"
|
||||
variant={optedOut ? "outline" : "default"}
|
||||
|
||||
Reference in New Issue
Block a user