Skip to content

Commit

Permalink
Use a cleaner design for the dashboard, without cards (#6358)
Browse files Browse the repository at this point in the history
  • Loading branch information
acelaya authored Jun 18, 2024
1 parent bdc131b commit 4e7d851
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 153 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from '@hypothesis/frontend-shared';
import classnames from 'classnames';
import { useMemo } from 'preact/hooks';
import { useParams } from 'wouter-preact';

Expand Down Expand Up @@ -52,14 +45,8 @@ export default function AssignmentActivity() {
);

return (
<Card>
<CardHeader
fullWidth
classes={classnames(
// Overwrite gap-x-2 and items-center from CardHeader
'flex-col !gap-x-0 !items-start',
)}
>
<div className="flex flex-col gap-y-5">
<div>
{assignment.data && (
<div className="mb-3 mt-1 w-full">
<DashboardBreadcrumbs
Expand All @@ -72,40 +59,38 @@ export default function AssignmentActivity() {
/>
</div>
)}
<CardTitle tagName="h2" data-testid="title">
<h2 className="text-lg text-brand font-semibold" data-testid="title">
{assignment.isLoading && 'Loading...'}
{assignment.error && 'Could not load assignment title'}
{assignment.data && title}
</CardTitle>
</CardHeader>
<CardContent>
<OrderableActivityTable
loading={students.isLoading}
title={assignment.isLoading ? 'Loading...' : title}
emptyMessage={
students.error ? 'Could not load students' : 'No students found'
</h2>
</div>
<OrderableActivityTable
loading={students.isLoading}
title={assignment.isLoading ? 'Loading...' : title}
emptyMessage={
students.error ? 'Could not load students' : 'No students found'
}
rows={rows}
columnNames={{
display_name: 'Student',
annotations: 'Annotations',
replies: 'Replies',
last_activity: 'Last Activity',
}}
defaultOrderField="display_name"
renderItem={(stats, field) => {
if (['annotations', 'replies'].includes(field)) {
return <div className="text-right">{stats[field]}</div>;
} else if (field === 'last_activity') {
return stats.last_activity
? formatDateTime(new Date(stats.last_activity))
: '';
}
rows={rows}
columnNames={{
display_name: 'Student',
annotations: 'Annotations',
replies: 'Replies',
last_activity: 'Last Activity',
}}
defaultOrderField="display_name"
renderItem={(stats, field) => {
if (['annotations', 'replies'].includes(field)) {
return <div className="text-right">{stats[field]}</div>;
} else if (field === 'last_activity') {
return stats.last_activity
? formatDateTime(new Date(stats.last_activity))
: '';
}

return stats[field] ?? `Student ${stats.id.substring(0, 10)}`;
}}
/>
</CardContent>
</Card>
return stats[field] ?? `Student ${stats.id.substring(0, 10)}`;
}}
/>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import {
Card,
CardContent,
CardHeader,
CardTitle,
Link,
} from '@hypothesis/frontend-shared';
import classnames from 'classnames';
import { Link } from '@hypothesis/frontend-shared';
import { useMemo } from 'preact/hooks';
import { useParams, Link as RouterLink } from 'wouter-preact';
import { Link as RouterLink, useParams } from 'wouter-preact';

import type { AssignmentsResponse, Course } from '../../api-types';
import { useConfig } from '../../config';
Expand Down Expand Up @@ -56,61 +49,52 @@ export default function CourseActivity() {
);

return (
<Card>
<CardHeader
fullWidth
classes={classnames(
// Overwrite gap-x-2 and items-center from CardHeader
'flex-col !gap-x-0 !items-start',
)}
>
<div className="flex flex-col gap-y-5">
<div>
<div className="mb-3 mt-1 w-full">
<DashboardBreadcrumbs />
</div>
<CardTitle tagName="h2" data-testid="title">
<h2 className="text-lg text-brand font-semibold" data-testid="title">
{course.isLoading && 'Loading...'}
{course.error && 'Could not load course title'}
{course.data && course.data.title}
</CardTitle>
</CardHeader>
<CardContent>
<OrderableActivityTable
loading={assignments.isLoading}
title={course.data?.title ?? 'Loading...'}
emptyMessage={
assignments.error
? 'Could not load assignments'
: 'No assignments found'
}
rows={rows}
columnNames={{
title: 'Assignment',
annotations: 'Annotations',
replies: 'Replies',
last_activity: 'Last Activity',
}}
defaultOrderField="title"
renderItem={(stats, field) => {
if (['annotations', 'replies'].includes(field)) {
return <div className="text-right">{stats[field]}</div>;
} else if (field === 'title') {
return (
<RouterLink href={assignmentURL(stats.id)} asChild>
<Link underline="always" variant="text">
{stats.title}
</Link>
</RouterLink>
);
}

</h2>
</div>
<OrderableActivityTable
loading={assignments.isLoading}
title={course.data?.title ?? 'Loading...'}
emptyMessage={
assignments.error
? 'Could not load assignments'
: 'No assignments found'
}
rows={rows}
columnNames={{
title: 'Assignment',
annotations: 'Annotations',
replies: 'Replies',
last_activity: 'Last Activity',
}}
defaultOrderField="title"
renderItem={(stats, field) => {
if (['annotations', 'replies'].includes(field)) {
return <div className="text-right">{stats[field]}</div>;
} else if (field === 'title') {
return (
stats.last_activity &&
formatDateTime(new Date(stats.last_activity))
<RouterLink href={assignmentURL(stats.id)} asChild>
<Link underline="always" variant="text">
{stats.title}
</Link>
</RouterLink>
);
}}
navigateOnConfirmRow={stats => assignmentURL(stats.id)}
/>
</CardContent>
</Card>
}

return (
stats.last_activity && formatDateTime(new Date(stats.last_activity))
);
}}
navigateOnConfirmRow={stats => assignmentURL(stats.id)}
/>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function DashboardApp() {
}>();

return (
<div className="flex flex-col min-h-screen gap-5 bg-grey-2">
<div className="flex flex-col min-h-screen gap-5">
<div
className={classnames(
'flex justify-center p-3 w-full',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ export type DashboardBreadcrumbsProps = {
function BreadcrumbLink({ title, href }: BreadcrumbLink) {
return (
<RouterLink href={href} asChild>
<Link underline="hover" variant="text-light" classes="truncate">
<Link
underline="always"
variant="text-light"
classes="truncate font-normal"
>
<ArrowLeftIcon className="inline-block md:hidden mr-1 align-sub" />
{title}
</Link>
Expand All @@ -34,7 +38,7 @@ export default function DashboardBreadcrumbs({
links = [],
}: DashboardBreadcrumbsProps) {
const linksWithHome = useMemo(
(): BreadcrumbLink[] => [{ title: 'Home', href: '' }, ...links],
(): BreadcrumbLink[] => [{ title: 'All courses', href: '' }, ...links],
[links],
);

Expand Down Expand Up @@ -62,7 +66,9 @@ export default function DashboardBreadcrumbs({
})}
>
<BreadcrumbLink href={href} title={title} />
{!isLastLink && <CaretRightIcon />}
{!isLastLink && (
<CaretRightIcon className="text-color-text-light" />
)}
</span>
);
})}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
Card,
CardContent,
CardHeader,
Link,
} from '@hypothesis/frontend-shared';
import { Link } from '@hypothesis/frontend-shared';
import { useMemo } from 'preact/hooks';
import { Link as RouterLink } from 'wouter-preact';

Expand Down Expand Up @@ -51,42 +46,40 @@ export default function OrganizationActivity({
);

return (
<Card>
<CardHeader title="Home" fullWidth />
<CardContent>
<OrderableActivityTable
loading={courses.isLoading}
title="Courses"
emptyMessage={
courses.error ? 'Could not load courses' : 'No courses found'
<div className="flex flex-col gap-y-5">
<h2 className="text-lg text-brand font-semibold">All courses</h2>
<OrderableActivityTable
loading={courses.isLoading}
title="Courses"
emptyMessage={
courses.error ? 'Could not load courses' : 'No courses found'
}
rows={rows}
columnNames={{
title: 'Course Title',
assignments: 'Assignments',
last_launched: 'Last launched',
}}
defaultOrderField="title"
renderItem={(stats, field) => {
if (field === 'assignments') {
return <div className="text-right">{stats[field]}</div>;
} else if (field === 'last_launched') {
return stats.last_launched
? formatDateTime(new Date(stats.last_launched))
: '';
}
rows={rows}
columnNames={{
title: 'Course Title',
assignments: 'Assignments',
last_launched: 'Last launched',
}}
defaultOrderField="title"
renderItem={(stats, field) => {
if (field === 'assignments') {
return <div className="text-right">{stats[field]}</div>;
} else if (field === 'last_launched') {
return stats.last_launched
? formatDateTime(new Date(stats.last_launched))
: '';
}

return (
<RouterLink href={urlPath`/courses/${String(stats.id)}`} asChild>
<Link underline="always" variant="text">
{stats.title}
</Link>
</RouterLink>
);
}}
navigateOnConfirmRow={stats => courseURL(stats.id)}
/>
</CardContent>
</Card>
return (
<RouterLink href={urlPath`/courses/${String(stats.id)}`} asChild>
<Link underline="always" variant="text">
{stats.title}
</Link>
</RouterLink>
);
}}
navigateOnConfirmRow={stats => courseURL(stats.id)}
/>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ describe('AssignmentActivity', () => {
fakeUseAPIFetch.returns({ isLoading: true });

const wrapper = createComponent();
const titleElement = wrapper.find('CardTitle[data-testid="title"]');
const titleElement = wrapper.find('[data-testid="title"]');
const tableElement = wrapper.find('OrderableActivityTable');

assert.equal(titleElement.text(), 'Loading...');
Expand All @@ -96,7 +96,7 @@ describe('AssignmentActivity', () => {
fakeUseAPIFetch.returns({ error: new Error('Something failed') });

const wrapper = createComponent();
const titleElement = wrapper.find('CardTitle[data-testid="title"]');
const titleElement = wrapper.find('[data-testid="title"]');
const tableElement = wrapper.find('OrderableActivityTable');

assert.equal(titleElement.text(), 'Could not load assignment title');
Expand All @@ -105,7 +105,7 @@ describe('AssignmentActivity', () => {

it('shows expected title', () => {
const wrapper = createComponent();
const titleElement = wrapper.find('CardTitle[data-testid="title"]');
const titleElement = wrapper.find('[data-testid="title"]');
const tableElement = wrapper.find('OrderableActivityTable');
const expectedTitle = 'Assignment: The title';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe('CourseActivity', () => {
fakeUseAPIFetch.returns({ isLoading: true });

const wrapper = createComponent();
const titleElement = wrapper.find('CardTitle[data-testid="title"]');
const titleElement = wrapper.find('[data-testid="title"]');
const tableElement = wrapper.find('OrderableActivityTable');

assert.equal(titleElement.text(), 'Loading...');
Expand All @@ -92,7 +92,7 @@ describe('CourseActivity', () => {
fakeUseAPIFetch.returns({ error: new Error('Something failed') });

const wrapper = createComponent();
const titleElement = wrapper.find('CardTitle[data-testid="title"]');
const titleElement = wrapper.find('[data-testid="title"]');
const tableElement = wrapper.find('OrderableActivityTable');

assert.equal(titleElement.text(), 'Could not load course title');
Expand All @@ -104,7 +104,7 @@ describe('CourseActivity', () => {

it('shows expected title', () => {
const wrapper = createComponent();
const titleElement = wrapper.find('CardTitle[data-testid="title"]');
const titleElement = wrapper.find('[data-testid="title"]');
const tableElement = wrapper.find('OrderableActivityTable');
const expectedTitle = 'The title';

Expand Down

0 comments on commit 4e7d851

Please sign in to comment.