feat(admin): add never-subscribed broadcast target with audience counts
Add a broadcast audience for users who registered but never had any subscription or trial (no Subscription rows at all), backed by a new get_user_ids_without_any_subscription DAL helper and a 'never' target in the webapp broadcast route. Add GET /api/admin/broadcast/audience-counts so the audience dropdown shows the recipient count next to each option, with graceful fallback when counts are unavailable.
This commit is contained in:
@@ -1,16 +1,27 @@
|
||||
<script>
|
||||
import { Textarea } from "$components/ui/index.js";
|
||||
import { Send } from "$components/ui/icons.js";
|
||||
import { getContext } from "svelte";
|
||||
import { getContext, onMount } from "svelte";
|
||||
import { Label } from "$components/ui/primitives.js";
|
||||
import { AdminButton, AdminSelect } from "$components/patterns/admin/index.js";
|
||||
|
||||
export let at;
|
||||
const broadcastStore = getContext("broadcastStore");
|
||||
|
||||
$: ({ broadcastTarget, broadcastText, broadcastBusy, broadcastResult } = $broadcastStore);
|
||||
$: ({ broadcastTarget, broadcastText, broadcastBusy, broadcastResult, broadcastCounts } =
|
||||
$broadcastStore);
|
||||
|
||||
const BROADCAST_TARGET_OPTIONS = broadcastStore.BROADCAST_TARGET_OPTIONS;
|
||||
|
||||
// Append the resolved audience size to each option once counts are loaded.
|
||||
$: targetOptions = BROADCAST_TARGET_OPTIONS.map((option) => {
|
||||
const count = broadcastCounts?.[option.value];
|
||||
return count == null ? option : { ...option, label: `${option.label} (${count})` };
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
broadcastStore.loadCounts();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="admin-card">
|
||||
@@ -24,7 +35,7 @@
|
||||
<span>{at("broadcast_label_audience", {}, "Аудитория")}</span>
|
||||
<AdminSelect
|
||||
value={broadcastTarget}
|
||||
items={BROADCAST_TARGET_OPTIONS}
|
||||
items={targetOptions}
|
||||
ariaLabel={at("broadcast_label_audience", {}, "Аудитория")}
|
||||
onValueChange={(value) => broadcastStore.updateField({ broadcastTarget: value })}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user