|
| 1 | +<script lang="ts"> |
| 2 | + import { Pause, Play } from '@lucide/svelte'; |
| 3 | + import type { PublicShareShocker, ShockerPermissions } from '$lib/api/internal/v1'; |
| 4 | + import { Button } from '$lib/components/ui/button'; |
| 5 | + import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '$lib/components/ui/card'; |
| 6 | + import { Label } from '$lib/components/ui/label'; |
| 7 | + import { Slider } from '$lib/components/ui/slider'; |
| 8 | + import { Switch } from '$lib/components/ui/switch'; |
| 9 | +
|
| 10 | + interface Props { |
| 11 | + shocker: PublicShareShocker; |
| 12 | + } |
| 13 | +
|
| 14 | + let { shocker }: Props = $props(); |
| 15 | +
|
| 16 | + // UI callbacks (stub implementations) |
| 17 | + const togglePlay = async (shockerId: string) => { |
| 18 | + // TODO: Call API to toggle play state |
| 19 | + }; |
| 20 | +
|
| 21 | + const toggleFeature = async (shockerId: string, feature: string, enabled: boolean) => { |
| 22 | + // TODO: Call API to toggle feature (shock, vibrate, sound, livecontrol, estop) |
| 23 | + }; |
| 24 | +
|
| 25 | + const updateDuration = async (shockerId: string, duration: number) => { |
| 26 | + // TODO: Call API to update duration limit |
| 27 | + }; |
| 28 | +
|
| 29 | + const updateIntensity = async (shockerId: string, intensity: number) => { |
| 30 | + // TODO: Call API to update intensity limit |
| 31 | + }; |
| 32 | +
|
| 33 | + const removeShocker = async (shockerId: string) => { |
| 34 | + // TODO: Call API to remove shocker from share |
| 35 | + }; |
| 36 | +</script> |
| 37 | + |
| 38 | +<Card> |
| 39 | + <CardHeader> |
| 40 | + <CardTitle class="flex items-center justify-between"> |
| 41 | + <span class="text-lg font-medium">{shocker.name}</span> |
| 42 | + <Button variant="outline" size="sm" onclick={() => togglePlay(shocker.id)}> |
| 43 | + {#if shocker.paused} |
| 44 | + <Pause size={16} /> |
| 45 | + {:else} |
| 46 | + <Play size={16} /> |
| 47 | + {/if} |
| 48 | + </Button> |
| 49 | + </CardTitle> |
| 50 | + </CardHeader> |
| 51 | + |
| 52 | + <CardContent class="space-y-4"> |
| 53 | + <!-- Feature Toggles --> |
| 54 | + <div class="space-y-2"> |
| 55 | + {#each ['shock', 'vibrate', 'sound', 'live'] satisfies (keyof ShockerPermissions)[] as feature} |
| 56 | + <div class="flex items-center justify-between"> |
| 57 | + <Label class="capitalize">{feature}</Label> |
| 58 | + <Switch |
| 59 | + checked={shocker.permissions[feature]} |
| 60 | + onCheckedChange={(e) => toggleFeature(shocker.id, feature, e)} |
| 61 | + /> |
| 62 | + </div> |
| 63 | + {/each} |
| 64 | + </div> |
| 65 | + |
| 66 | + <!-- Duration Slider --> |
| 67 | + <div class="space-y-1"> |
| 68 | + <Label>Duration: {shocker.limits.duration}s</Label> |
| 69 | + <Slider type="single" value={shocker.limits.duration ?? 0} min={1} max={120} step={1} /> |
| 70 | + </div> |
| 71 | + |
| 72 | + <!-- Intensity Slider --> |
| 73 | + <div class="space-y-1"> |
| 74 | + <Label>Intensity: {shocker.limits.intensity}%</Label> |
| 75 | + <Slider type="single" value={shocker.limits.intensity ?? 0} min={0} max={100} step={5} /> |
| 76 | + </div> |
| 77 | + </CardContent> |
| 78 | + |
| 79 | + <CardFooter> |
| 80 | + <Button variant="destructive" size="sm" onclick={() => removeShocker(shocker.id)}> |
| 81 | + Remove |
| 82 | + </Button> |
| 83 | + </CardFooter> |
| 84 | +</Card> |
0 commit comments