96 lines
3.0 KiB
Svelte
96 lines
3.0 KiB
Svelte
<script lang="ts">
|
|
interface Props {
|
|
selected: string[];
|
|
}
|
|
|
|
let { selected = $bindable([]) }: Props = $props();
|
|
|
|
const channels = [
|
|
{ value: 'IN_APP', label: 'In-App', description: 'Notifications appear in the app' },
|
|
{ value: 'EMAIL', label: 'Email', description: 'Send email notifications' },
|
|
{ value: 'SMS', label: 'SMS', description: 'Send text message notifications' }
|
|
];
|
|
|
|
function toggle(value: string) {
|
|
if (selected.includes(value)) {
|
|
selected = selected.filter((v) => v !== value);
|
|
} else {
|
|
selected = [...selected, value];
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<div>
|
|
<span class="mb-2 block text-sm font-medium text-theme">
|
|
Notification Channels <span class="text-error-500">*</span>
|
|
</span>
|
|
|
|
<div class="flex flex-wrap gap-3">
|
|
{#each channels as channel (channel.value)}
|
|
<button
|
|
type="button"
|
|
onclick={() => toggle(channel.value)}
|
|
class="flex items-center gap-2 rounded-lg border px-4 py-2.5 text-left transition-colors {selected.includes(
|
|
channel.value
|
|
)
|
|
? 'border-primary-500 bg-primary-500/10 text-primary-600 dark:text-primary-400'
|
|
: 'border-theme bg-theme hover:bg-black/5 dark:hover:bg-white/10'}"
|
|
>
|
|
<span class="flex h-5 w-5 items-center justify-center">
|
|
{#if channel.value === 'IN_APP'}
|
|
<svg class="h-5 w-5" style="fill: none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"
|
|
/>
|
|
</svg>
|
|
{:else if channel.value === 'EMAIL'}
|
|
<svg class="h-5 w-5" style="fill: none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
|
|
/>
|
|
</svg>
|
|
{:else}
|
|
<svg class="h-5 w-5" style="fill: none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"
|
|
/>
|
|
</svg>
|
|
{/if}
|
|
</span>
|
|
<span class="flex flex-col">
|
|
<span class="text-sm font-medium">{channel.label}</span>
|
|
<span class="text-xs text-theme-muted">{channel.description}</span>
|
|
</span>
|
|
{#if selected.includes(channel.value)}
|
|
<svg
|
|
class="ml-2 h-5 w-5 text-primary-500"
|
|
style="fill: none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M5 13l4 4L19 7"
|
|
/>
|
|
</svg>
|
|
{/if}
|
|
</button>
|
|
{/each}
|
|
</div>
|
|
|
|
{#if selected.length === 0}
|
|
<p class="mt-2 text-xs text-error-500">Please select at least one channel</p>
|
|
{/if}
|
|
</div>
|