Skip to content

Commit ea3cee9

Browse files
committed
Finish up the rest of user shares
1 parent fc54b01 commit ea3cee9

File tree

5 files changed

+154
-36
lines changed

5 files changed

+154
-36
lines changed

src/routes/(authenticated)/shares/user/incoming/+page.svelte

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,27 @@
33
import * as Table from '$lib/components/ui/table';
44
import { UserShares, refreshUserShares } from '$lib/stores/UserSharesStore';
55
import IncomingShareItem from './incoming-share-item.svelte';
6+
import ManageShare from './manage-share.svelte';
67
78
let refreshPromise = $state(refreshUserShares());
9+
10+
let manageShareDrawerOpen = $state(false);
11+
let manageShareDrawerOpenCount = $state(0);
12+
let manageIndex = $state(0);
13+
14+
function openManageDrawer(userShareIndex: number) {
15+
manageIndex = userShareIndex;
16+
manageShareDrawerOpenCount += 1;
17+
manageShareDrawerOpen = true;
18+
}
819
</script>
920

21+
{#key manageShareDrawerOpenCount}
22+
{#if $UserShares.outgoing[manageIndex] !== undefined}
23+
<ManageShare storeIndex={manageIndex} bind:editDrawer={manageShareDrawerOpen} />
24+
{/if}
25+
{/key}
26+
1027
{#await refreshPromise}
1128
<div class="flex justify-center items-center h-full w-full">
1229
<LoadingCircle />
@@ -16,7 +33,7 @@
1633
<Table.Root>
1734
<Table.Body>
1835
{#each $UserShares.incoming as incomingShare, i (incomingShare.id)}
19-
<IncomingShareItem share={incomingShare} />
36+
<IncomingShareItem share={incomingShare} onOpenEdit={() => openManageDrawer(i)} />
2037
{/each}
2138
</Table.Body>
2239
</Table.Root>

src/routes/(authenticated)/shares/user/incoming/incoming-share-item.svelte

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
1616
interface Props {
1717
share: V2UserSharesListItem;
18+
onOpenEdit: () => void;
1819
}
1920
20-
let { share = $bindable() }: Props = $props();
21+
let { share = $bindable(), onOpenEdit }: Props = $props();
2122
2223
async function removeShareCall(value: V2UserSharesListItem) {
2324
try {
@@ -44,7 +45,7 @@
4445
<p>Are you sure you want to remove the share for <strong>{invite.name}</strong>?</p>
4546
{/snippet}
4647

47-
<Table.Row>
48+
<Table.Row onclick={onOpenEdit}>
4849
<Table.Cell class="flex items-center font-medium">
4950
<Avatar.Root class="h-15 w-15">
5051
<Avatar.Image src={share.image} alt="User Avatar" />
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<script lang="ts">
2+
import { Trash } from '@lucide/svelte';
3+
import { shockersV1Api } from '$lib/api';
4+
import type { UserShareInfo } from '$lib/api/internal/v2';
5+
import LoadingCircle from '$lib/components/svg/LoadingCircle.svelte';
6+
import * as Avatar from '$lib/components/ui/avatar';
7+
import Button from '$lib/components/ui/button/button.svelte';
8+
import * as Drawer from '$lib/components/ui/drawer';
9+
import * as Table from '$lib/components/ui/table/index.js';
10+
import { handleApiError } from '$lib/errorhandling/apiErrorHandling';
11+
import { openConfirmDialog } from '$lib/stores/ConfirmDialogStore';
12+
import { UserShares, refreshUserShares } from '$lib/stores/UserSharesStore';
13+
import { toast } from 'svelte-sonner';
14+
import { derived } from 'svelte/store';
15+
import { UserStore } from '$lib/stores/UserStore';
16+
17+
interface Props {
18+
storeIndex: number;
19+
editDrawer: boolean;
20+
}
21+
22+
let { storeIndex, editDrawer = $bindable() }: Props = $props();
23+
24+
let userShare = derived(UserShares, ($a) => $a.incoming[storeIndex]);
25+
26+
async function deleteShockerShare(shocker: UserShareInfo) {
27+
try {
28+
await shockersV1Api.shockerShockerShareRemove(shocker.id, $UserStore.self!.id);
29+
toast.success(
30+
`Successfully removed incoming Shocker Share ${shocker.name} by ${$userShare.name}`
31+
);
32+
} catch (error) {
33+
handleApiError(error);
34+
throw error;
35+
} finally {
36+
refreshUserShares();
37+
}
38+
}
39+
40+
function handleDeleteClick(shocker: UserShareInfo) {
41+
openConfirmDialog({
42+
title: 'Confirm removal of Incoming Shocker Share',
43+
descSnippet: deleteConfirmDesc,
44+
data: shocker,
45+
onConfirm: deleteShockerShare,
46+
confirmButtonText: 'Remove Share',
47+
});
48+
}
49+
</script>
50+
51+
{#snippet deleteConfirmDesc(shocker: UserShareInfo)}
52+
<p>
53+
Are you sure you want to remove the shocker share <strong>{shocker.name}</strong> by
54+
<strong>{$userShare.name}</strong>?
55+
</p>
56+
{/snippet}
57+
58+
<Drawer.Root bind:open={editDrawer} direction="right">
59+
<Drawer.Content>
60+
<div class="mx-auto w-full max-h-[100vh] flex flex-col">
61+
<Drawer.Header class="shrink-0">
62+
<Drawer.Description>Manage Shares from</Drawer.Description>
63+
<Drawer.Title class="flex items-center gap-2 mt-1">
64+
<Avatar.Root class="size-10">
65+
<Avatar.Image src={$userShare.image} alt="User Avatar" />
66+
<Avatar.Fallback>
67+
{$userShare.name.charAt(0)}
68+
</Avatar.Fallback>
69+
</Avatar.Root>
70+
<b>{$userShare.name}</b></Drawer.Title
71+
>
72+
</Drawer.Header>
73+
<div class="rounded-md border overflow-y-auto m-4">
74+
<Table.Root>
75+
<Table.Body>
76+
{#each $userShare.shares as shocker (shocker.id)}
77+
<Table.Row>
78+
<Table.Cell>
79+
{shocker.name}
80+
</Table.Cell>
81+
<Table.Cell class="w-0">
82+
<Button variant="destructive" onclick={() => handleDeleteClick(shocker)}>
83+
<Trash />
84+
</Button>
85+
</Table.Cell>
86+
</Table.Row>
87+
{/each}
88+
</Table.Body>
89+
</Table.Root>
90+
</div>
91+
</div>
92+
</Drawer.Content>
93+
</Drawer.Root>
94+
95+
<style>
96+
:global(.data-\[vaul-drawer-direction\=right\]\:sm\:max-w-sm) {
97+
&[data-vaul-drawer-direction='right'] {
98+
@media (width >= 40rem) {
99+
max-width: 33rem;
100+
}
101+
}
102+
}
103+
</style>

src/routes/(authenticated)/shares/user/invites/incoming-invite-item.svelte

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -69,35 +69,31 @@
6969
<p class="ml-4">{shareInvite.owner.name}</p>
7070
</Table.Cell>
7171
<Table.Cell class="flex-auto">
72-
<Tooltip.Root>
73-
<Tooltip.Trigger>
74-
<span
75-
class="bg-sidebar flex items-center rounded-2xl px-1.5 py-0.5 ring-1 ring-slate-800 w-max"
76-
>
77-
<Zap size="15" />
78-
<p class="ml-2 inline-block sm:hidden">{shareInvite.shockers.length}</p>
79-
<div class="hidden sm:inline-block">
80-
{#each shareInvite.shockers as shocker}
81-
<Tooltip.Root>
82-
<Tooltip.Trigger>
83-
<Badge class="ml-2">{shocker.name}</Badge>
84-
</Tooltip.Trigger>
85-
<Tooltip.Content>
86-
<PermissionTooltip permAndLimits={shocker} />
87-
</Tooltip.Content>
88-
</Tooltip.Root>
89-
{/each}
90-
</div>
91-
</span>
92-
</Tooltip.Trigger>
93-
<Tooltip.Content>
94-
<p>Shared shockers</p>
95-
</Tooltip.Content>
96-
</Tooltip.Root>
72+
<span
73+
class="bg-sidebar flex items-center rounded-2xl px-1.5 py-0.5 ring-1 ring-slate-800 w-max"
74+
>
75+
<Zap size="15" />
76+
<p class="ml-2 inline-block sm:hidden">{shareInvite.shockers.length}</p>
77+
<div class="hidden sm:inline-block">
78+
{#each shareInvite.shockers as shocker}
79+
<Tooltip.Root>
80+
<Tooltip.Trigger>
81+
<Badge class="ml-2">{shocker.name}</Badge>
82+
</Tooltip.Trigger>
83+
<Tooltip.Content>
84+
<PermissionTooltip permAndLimits={shocker} />
85+
</Tooltip.Content>
86+
</Tooltip.Root>
87+
{/each}
88+
</div>
89+
</span>
9790
</Table.Cell>
9891
<Table.Cell class="w-0 flex-none">
9992
<Tooltip.Root>
100-
<Tooltip.Trigger class={cn('size-9 mr-4', buttonVariants({ variant: 'default' }))} onclick={acceptInvite}>
93+
<Tooltip.Trigger
94+
class={cn('size-9 mr-4', buttonVariants({ variant: 'default' }))}
95+
onclick={acceptInvite}
96+
>
10197
<Check />
10298
</Tooltip.Trigger>
10399
<Tooltip.Content>

src/routes/(authenticated)/shares/user/outgoing/edit-share.svelte

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<script lang="ts">
22
import { Trash } from '@lucide/svelte';
3-
import { shockerSharesV2Api, shockersV1Api } from '$lib/api';
4-
import type { V2UserSharesListItem } from '$lib/api/internal/v2';
3+
import { shockersV1Api } from '$lib/api';
54
import { ComparePermissionsAndLimits } from '$lib/comparers/UserShareComparer';
65
import LoadingCircle from '$lib/components/svg/LoadingCircle.svelte';
76
import * as Avatar from '$lib/components/ui/avatar';
@@ -12,8 +11,8 @@
1211
import MultiPauseToggle from '$lib/components/utils/MultiPauseToggle.svelte';
1312
import PauseToggle from '$lib/components/utils/PauseToggle.svelte';
1413
import { handleApiError } from '$lib/errorhandling/apiErrorHandling';
15-
import { ConfirmDialogStore, openConfirmDialog } from '$lib/stores/ConfirmDialogStore';
16-
import { UserShares } from '$lib/stores/UserSharesStore';
14+
import { openConfirmDialog } from '$lib/stores/ConfirmDialogStore';
15+
import { UserShares, refreshUserShares } from '$lib/stores/UserSharesStore';
1716
import { onMount } from 'svelte';
1817
import { toast } from 'svelte-sonner';
1918
import { derived } from 'svelte/store';
@@ -155,13 +154,15 @@
155154
});
156155
}
157156
158-
async function deleteShockerShare(shockerId: EditableShare) {
157+
async function deleteShockerShare(shocker: EditableShare) {
159158
try {
160-
await shockersV1Api.shockerShockerShareRemove(shockerId.id, $userShare.id);
161-
toast.success(`Successfully removed shocker share ${shockerId}`);
159+
await shockersV1Api.shockerShockerShareRemove(shocker.id, $userShare.id);
160+
toast.success(`Successfully removed shocker share ${shocker.name}`);
162161
} catch (error) {
163162
handleApiError(error);
164163
throw error;
164+
} finally {
165+
refreshUserShares();
165166
}
166167
}
167168

0 commit comments

Comments
 (0)