diff --git a/packages/frontend/src/lib/components/recording-card/recording-card.svelte b/packages/frontend/src/lib/components/recording-card/recording-card.svelte index e4aa691..d7292c6 100644 --- a/packages/frontend/src/lib/components/recording-card/recording-card.svelte +++ b/packages/frontend/src/lib/components/recording-card/recording-card.svelte @@ -8,10 +8,12 @@ interface Props { recording: Recording; onPlay?: (id: string) => void; + onPublish?: (id: string) => void; + onUnpublish?: (id: string) => void; onDelete?: (id: string) => void; } - let { recording, onPlay, onDelete }: Props = $props(); + let { recording, onPlay, onPublish, onUnpublish, onDelete }: Props = $props(); function formatDuration(ms: number): string { const totalSeconds = Math.floor(ms / 1000); @@ -149,12 +151,35 @@ {$_("recording_card.play")} {/if} + {#if onPublish && recording.status === "draft"} + + {/if} + {#if onUnpublish && recording.status === "published"} + + {/if} {#if onDelete} diff --git a/packages/frontend/src/lib/i18n/locales/en.ts b/packages/frontend/src/lib/i18n/locales/en.ts index f4cfcdd..5fcf141 100644 --- a/packages/frontend/src/lib/i18n/locales/en.ts +++ b/packages/frontend/src/lib/i18n/locales/en.ts @@ -151,6 +151,10 @@ export default { delete_confirm: "Are you sure you want to delete this recording?", delete_success: "Recording deleted successfully", delete_error: "Failed to delete recording", + publish_success: "Recording published successfully", + publish_error: "Failed to publish recording", + unpublish_success: "Recording unpublished", + unpublish_error: "Failed to unpublish recording", }, }, recording_card: { @@ -161,6 +165,8 @@ export default { status_draft: "Draft", status_published: "Published", play: "Play", + publish: "Publish", + unpublish: "Unpublish", edit: "Edit", delete: "Delete", public: "Public", diff --git a/packages/frontend/src/lib/services.ts b/packages/frontend/src/lib/services.ts index 9fe0c32..559cea2 100644 --- a/packages/frontend/src/lib/services.ts +++ b/packages/frontend/src/lib/services.ts @@ -902,6 +902,32 @@ export async function createRecording( ); } +const UPDATE_RECORDING_MUTATION = gql` + mutation UpdateRecording($id: String!, $status: String, $public: Boolean) { + updateRecording(id: $id, status: $status, public: $public) { + id + status + public + } + } +`; + +export async function updateRecording( + id: string, + fields: { status?: string; public?: boolean }, +) { + return loggedApiCall( + "updateRecording", + async () => { + const data = await getGraphQLClient().request<{ updateRecording: Recording }>( + UPDATE_RECORDING_MUTATION, + { id, ...fields }, + ); + return data.updateRecording; + }, + ); +} + const DELETE_RECORDING_MUTATION = gql` mutation DeleteRecording($id: String!) { deleteRecording(id: $id) diff --git a/packages/frontend/src/routes/me/recordings/+page.svelte b/packages/frontend/src/routes/me/recordings/+page.svelte index 8ca33cd..023048f 100644 --- a/packages/frontend/src/routes/me/recordings/+page.svelte +++ b/packages/frontend/src/routes/me/recordings/+page.svelte @@ -3,7 +3,7 @@ import { _ } from "svelte-i18n"; import { goto } from "$app/navigation"; import { toast } from "svelte-sonner"; - import { deleteRecording } from "$lib/services"; + import { deleteRecording, updateRecording } from "$lib/services"; import { Button } from "$lib/components/ui/button"; import * as Empty from "$lib/components/ui/empty"; import * as Dialog from "$lib/components/ui/dialog"; @@ -38,6 +38,26 @@ } } + async function handlePublishRecording(id: string) { + try { + await updateRecording(id, { status: "published" }); + recordings = recordings.map((r) => (r.id === id ? { ...r, status: "published" } : r)); + toast.success($_("me.recordings.publish_success")); + } catch { + toast.error($_("me.recordings.publish_error")); + } + } + + async function handleUnpublishRecording(id: string) { + try { + await updateRecording(id, { status: "draft" }); + recordings = recordings.map((r) => (r.id === id ? { ...r, status: "draft" } : r)); + toast.success($_("me.recordings.unpublish_success")); + } catch { + toast.error($_("me.recordings.unpublish_error")); + } + } + function handlePlayRecording(id: string) { goto(`/play?recording=${id}`); } @@ -46,15 +66,8 @@