Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 22 additions & 25 deletions src/features/dashboard/components/HomeworkDetailActions.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import type { Component } from "svelte";
import CheckCircleIcon from "@lucide/svelte/icons/check-circle";
import RotateCcwIcon from "@lucide/svelte/icons/rotate-ccw";
import { Button } from "$lib/components/ui/button/index.js";
import { Separator } from "$lib/components/ui/separator/index.js";
import type {
Expand All @@ -9,40 +10,36 @@ import type {
DashboardHomeworkDetailItem,
} from "./dashboard-homework-detail-types";

export let SelectedCompletionIcon: Component;
export let homework: DashboardHomeworkDetailItem;
export let homeworkCompletionActionLabel: DashboardHomeworkDetailAction;
export let homeworkDetailHref: DashboardHomeworkDetailAction;
export let homeworkSavingById: Record<string, boolean>;
export let homeworkSectionHref: DashboardHomeworkDetailAction;
export let homeworksCopy: DashboardHomeworkDetailCopy;
export let selectedCourseLabel: string;
export let toggleHomeworkCompletion: DashboardHomeworkCompletionToggle;
</script>

<div class="grid gap-4">
<Separator />
<div class="flex flex-wrap items-center justify-between gap-2">
<Button href={homeworkSectionHref(homework)} variant="outline">
{selectedCourseLabel}
<div class="flex flex-wrap items-center justify-end gap-2">
<Button
disabled={homeworkSavingById[homework.id]}
type="button"
variant="outline"
onclick={() => {
toggleHomeworkCompletion(homework);
}}
>
{#if homework.completion}
<RotateCcwIcon data-icon="inline-start" />
{:else}
<CheckCircleIcon data-icon="inline-start" />
{/if}
{homeworkSavingById[homework.id]
? homeworksCopy.saving
: homeworkCompletionActionLabel(homework)}
</Button>
<Button href={homeworkDetailHref(homework)}>
{homeworksCopy.viewDetails}
</Button>
<div class="flex flex-wrap justify-end gap-2">
<Button
disabled={homeworkSavingById[homework.id]}
type="button"
variant="outline"
onclick={() => {
if (homework) toggleHomeworkCompletion(homework);
}}
>
<SelectedCompletionIcon data-icon="inline-start" />
{homeworkSavingById[homework.id]
? homeworksCopy.saving
: homeworkCompletionActionLabel(homework)}
</Button>
<Button href={homeworkDetailHref(homework)}>
{homeworksCopy.viewDetails}
</Button>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script lang="ts">
import { commentTargetPermalinkBaseHref } from "@/features/comments/lib/comment-panel-controller";
import { Separator } from "$lib/components/ui/separator/index.js";
import type {
DashboardHomeworkCommentsPanel,
DashboardHomeworkDetailCopy,
Expand All @@ -20,16 +19,11 @@ $: permalinkBaseHref = homework.section?.jwId
: null;
</script>

<aside class="min-w-0">
<Separator class="mb-5 lg:hidden" />
<div class="lg:grid lg:grid-cols-[auto_minmax(0,1fr)] lg:gap-5">
<Separator class="hidden lg:block" orientation="vertical" />
<div class="min-w-0">
<h3 class="font-semibold text-base">{homeworksCopy.commentsTitle}</h3>
<p class="mt-1 mb-3 text-muted-foreground text-sm">{homeworksCopy.commentsLabel}</p>
{#key `comments:homework:${homework.id}`}
<CommentsPanel {permalinkBaseHref} targetId={homework.id} targetType="homework" />
{/key}
</div>
</div>
</aside>
{#key `comments:homework:${homework.id}`}
<CommentsPanel
heading={homeworksCopy.commentsTitle}
{permalinkBaseHref}
targetId={homework.id}
targetType="homework"
/>
{/key}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export let homework: DashboardHomeworkDetailItem;
export let homeworksCopy: DashboardHomeworkDetailCopy;
</script>

<Item.Root variant="outline" class="items-start">
<Item.Root variant="muted" class="items-start p-4">
<Item.Content>
{#if homework.description}
<MarkdownPreview
Expand Down
95 changes: 36 additions & 59 deletions src/features/dashboard/components/HomeworkDetailDialog.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
<script lang="ts">
import CheckCircleIcon from "@lucide/svelte/icons/check-circle";
import RefreshCw from "@lucide/svelte/icons/refresh-cw";
import type { DashboardMyHomeworksCopy } from "@/features/dashboard/lib/dashboard-controller-types";
import * as Dialog from "$lib/components/ui/dialog/index.js";
import { ScrollArea } from "$lib/components/ui/scroll-area/index.js";
import DetailDialog from "$lib/components/DetailDialog.svelte";
import type {
DashboardHomeworkCommentsPanel,
DashboardHomeworkCompletionToggle,
Expand All @@ -26,68 +22,49 @@ export let homeworkDetailHref: DashboardHomeworkDetailAction;
export let homeworkEtaLabel: DashboardHomeworkDetailFormatter;
export let homeworkCourseLabel: DashboardHomeworkDetailAction;
export let homeworkSavingById: Record<string, boolean>;
export let homeworkSectionHref: DashboardHomeworkDetailAction;
export let homeworksCopy: DashboardHomeworkDetailCopy;
export let homeworkCopy: DashboardMyHomeworksCopy;
export let homeworkStatus: DashboardHomeworkDetailAction;
export let onClose: () => void;
export let toggleHomeworkCompletion: DashboardHomeworkCompletionToggle;
</script>

{#if homework}
<Dialog.Root
open={true}
onOpenChange={(open) => {
if (!open) onClose();
}}
{@const selected = homework}
<!-- Cross-section list: the course is the disambiguating context, so it stays
in the subtitle. Documented popup order: description, due summary,
vertical metadata, action controls, discussion. -->
<DetailDialog
onClose={onClose}
subtitle={homeworkCourseLabel(selected)}
title={selected.title}
>
<Dialog.Content
class="max-w-5xl sm:max-w-5xl"
>
{@const selectedCourseLabel = homeworkCourseLabel(homework)}
{@const SelectedCompletionIcon = homework.completion ? RefreshCw : CheckCircleIcon}
<Dialog.Header>
<Dialog.Title>{homework.title}</Dialog.Title>
<Dialog.Description>
{selectedCourseLabel} · {homeworkCopy.due}:
{fmtDate(homework.submissionDueAt)}
</Dialog.Description>
</Dialog.Header>
<ScrollArea class="h-[min(70vh,44rem)]">
<div class="grid gap-5 px-5 py-4 lg:grid-cols-[minmax(0,1fr)_minmax(20rem,24rem)]">
<div class="grid min-w-0 gap-4">
<HomeworkDetailDescription
{homework}
{homeworksCopy}
/>
{#snippet body()}
<HomeworkDetailDescription homework={selected} {homeworksCopy} />

<HomeworkDetailMetadata
{fmtDate}
{homework}
{homeworkEtaLabel}
{homeworksCopy}
{homeworkStatus}
/>
<HomeworkDetailMetadata
{fmtDate}
homework={selected}
{homeworkEtaLabel}
{homeworkStatus}
{homeworksCopy}
/>

<HomeworkDetailActions
{SelectedCompletionIcon}
{homework}
{homeworkCompletionActionLabel}
{homeworkDetailHref}
{homeworkSavingById}
{homeworkSectionHref}
{homeworksCopy}
{selectedCourseLabel}
{toggleHomeworkCompletion}
/>
</div>
<HomeworkDetailCommentsAside
{CommentsPanel}
{homework}
{homeworksCopy}
/>
</div>
</ScrollArea>
</Dialog.Content>
</Dialog.Root>
<HomeworkDetailActions
homework={selected}
{homeworkCompletionActionLabel}
{homeworkDetailHref}
{homeworkSavingById}
{homeworksCopy}
{toggleHomeworkCompletion}
/>
{/snippet}

{#snippet aside()}
<HomeworkDetailCommentsAside
{CommentsPanel}
homework={selected}
{homeworksCopy}
/>
{/snippet}
</DetailDialog>
{/if}
78 changes: 31 additions & 47 deletions src/features/dashboard/components/HomeworkDetailMetadata.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
<script lang="ts">
import { Badge } from "$lib/components/ui/badge/index.js";
import * as Item from "$lib/components/ui/item/index.js";
import { Separator } from "$lib/components/ui/separator/index.js";
import HomeworkDetailTags from "@/features/homeworks/components/HomeworkDetailTags.svelte";
import HomeworkDueSummary from "@/features/homeworks/components/HomeworkDueSummary.svelte";
import HomeworkMetaList from "@/features/homeworks/components/HomeworkMetaList.svelte";
import {
buildHomeworkDetailTags,
buildHomeworkDueSummary,
buildHomeworkMetadataRows,
} from "@/features/homeworks/lib/homework-detail-meta";
import type {
DashboardHomeworkDetailAction,
DashboardHomeworkDetailCopy,
Expand All @@ -12,51 +17,30 @@ import type {
export let fmtDate: DashboardHomeworkDetailFormatter;
export let homework: DashboardHomeworkDetailItem;
export let homeworkEtaLabel: DashboardHomeworkDetailFormatter;
export let homeworksCopy: DashboardHomeworkDetailCopy;
export let homeworkStatus: DashboardHomeworkDetailAction;
export let homeworksCopy: DashboardHomeworkDetailCopy;

$: dueSummary = buildHomeworkDueSummary({
completed: Boolean(homework.completion),
dueLabel: homeworksCopy.submissionDue,
etaLabel: homeworkEtaLabel(homework.submissionDueAt),
formatDate: fmtDate,
homework,
statusLabel: homeworkStatus(homework),
});
$: metaRows = buildHomeworkMetadataRows({
formatDate: fmtDate,
homework,
labels: {
publishedAt: homeworksCopy.homeworkPublishedAt,
submissionStart: homeworksCopy.submissionStart,
},
});
$: tags = buildHomeworkDetailTags({ homework, labels: homeworksCopy });
</script>

<Item.Root variant="muted" class="items-start">
<Item.Header>
<Item.Content>
<Item.Description>
{homeworksCopy.submissionDue}
</Item.Description>
<Item.Title>{fmtDate(homework.submissionDueAt)}</Item.Title>
</Item.Content>
<Item.Actions>
<Badge variant={homework.completion ? "default" : "secondary"}>
{homeworkStatus(homework)}
</Badge>
</Item.Actions>
</Item.Header>
<Item.Description>{homeworkEtaLabel(homework.submissionDueAt)}</Item.Description>
<Separator />
<Item.Group class="grid gap-3 sm:grid-cols-2">
<Item.Root variant="outline" size="sm">
<Item.Content>
<Item.Description>{homeworksCopy.submissionStart}</Item.Description>
<Item.Title>{fmtDate(homework.submissionStartAt)}</Item.Title>
</Item.Content>
</Item.Root>
<Item.Root variant="outline" size="sm">
<Item.Content>
<Item.Description>{homeworksCopy.homeworkPublishedAt}</Item.Description>
<Item.Title>{fmtDate(homework.publishedAt)}</Item.Title>
</Item.Content>
</Item.Root>
</Item.Group>
</Item.Root>
<HomeworkDueSummary summary={dueSummary} />

<HomeworkMetaList rows={metaRows} />

<div class="flex flex-wrap gap-2">
{#if homework.isMajor}
<Badge variant="secondary">
{homeworksCopy.tagMajor}
</Badge>
{/if}
{#if homework.requiresTeam}
<Badge variant="outline">
{homeworksCopy.tagTeam}
</Badge>
{/if}
</div>
<HomeworkDetailTags {tags} />
2 changes: 0 additions & 2 deletions src/features/dashboard/components/HomeworksTab.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,11 @@ $: ({
bind:createHomeworkSubmissionStartAt
{fmtDate}
{homeworkCompletionActionLabel}
{homeworkCopy}
{homeworkCourseLabel}
{homeworkDetailHref}
{homeworkEtaLabel}
{homeworksCopy}
{homeworkSavingById}
{homeworkSectionHref}
{homeworkSectionLabel}
{homeworkStatus}
{isCreatingHomework}
Expand Down
4 changes: 0 additions & 4 deletions src/features/dashboard/components/HomeworksTabDialogs.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,11 @@ export let createHomeworkSubmissionDueAt: string;
export let createHomeworkSubmissionStartAt: string;
export let fmtDate: DashboardHomeworkDetailFormatter;
export let homeworkCompletionActionLabel: HomeworkAction;
export let homeworkCopy: DashboardMyHomeworksCopy;
export let homeworkCourseLabel: HomeworkAction;
export let homeworkDetailHref: HomeworkAction;
export let homeworkEtaLabel: DashboardHomeworkDetailFormatter;
export let homeworksCopy: DashboardHomeworksCopy;
export let homeworkSavingById: Record<string, boolean>;
export let homeworkSectionHref: HomeworkAction;
export let homeworkSectionLabel: (
section: DashboardHomeworkCreateSection,
) => string;
Expand Down Expand Up @@ -92,9 +90,7 @@ export let toggleHomeworkCompletion: (
{homeworkEtaLabel}
{homeworkCourseLabel}
{homeworkSavingById}
{homeworkSectionHref}
{homeworksCopy}
{homeworkCopy}
{homeworkStatus}
onClose={() => {
selectedHomework = null;
Expand Down
Loading