Skip to content

Commit ba4b2eb

Browse files
committed
feat: add client dates & sorting
1 parent 3d116eb commit ba4b2eb

File tree

3 files changed

+68
-17
lines changed

3 files changed

+68
-17
lines changed

src/components/home/Client.svelte

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44
export let client: ClientItem;
55
66
const { name, description, website, logo, cover } = client;
7+
8+
const formatDate = (date: Date) => date.toLocaleDateString('en-US', {
9+
month: 'long',
10+
year: 'numeric',
11+
});
12+
13+
const start = formatDate(client.dates.start);
14+
const end = client.dates.end ? formatDate(client.dates.end) : 'Present';
715
</script>
816

917
<a href={website} rel="noopener noreferrer" target="_blank">
@@ -20,9 +28,15 @@
2028
</div>
2129
{/if}
2230

23-
<div class="px-4 pb-4">
24-
<h2 class="font-medium text-blue-400">{name}</h2>
25-
<p class="text-body line-clamp-2 text-ellipsis">{description}</p>
31+
<div class="px-4 pb-4 flex flex-col justify-between h-full">
32+
<div>
33+
<h2 class="font-medium text-blue-400">{name}</h2>
34+
<p class="text-body line-clamp-2 text-ellipsis">{description}</p>
35+
</div>
36+
37+
<div class="pt-2">
38+
<p class="text-sm text-neutral-500 dark:text-neutral-400">{start} - {end}</p>
39+
</div>
2640
</div>
2741
</div>
2842
</a>

src/routes/+page.server.ts

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
import { NOTION_CLIENTS_DB_ID, NOTION_KEY } from '$env/static/private';
23
import { Client } from '@notionhq/client';
3-
import type { PageServerLoad } from './$types';
4-
import { NOTION_KEY, NOTION_CLIENTS_DB_ID } from '$env/static/private';
54
import type { PageObjectResponse } from '@notionhq/client/build/src/api-endpoints';
5+
import { convertNotionDates, convertRichText } from '../utils/notion';
6+
import type { PageServerLoad } from './$types';
67

78
const notion = new Client({ auth: NOTION_KEY });
89

@@ -20,19 +21,37 @@ export const load: PageServerLoad = async ({ fetch }) => {
2021
}
2122
});
2223

23-
const clients: ClientItem[] = pages.results.map((_page) => {
24-
const page = _page as PageObjectResponse;
25-
const properties = page.properties;
24+
const clients: ClientItem[] = pages.results
25+
.map((_page) => {
26+
const page = _page as PageObjectResponse;
27+
const properties = page.properties;
2628

27-
return {
28-
name: (properties.Name as any).title[0].plain_text,
29-
description: (properties.Description as any).rich_text[0]?.plain_text ?? "Very mysterious!",
30-
website: (properties.Website as any).url,
31-
32-
logo: (page.icon as any).file.url,
33-
cover: (page.cover as any).file.url,
34-
}
35-
});
29+
// Type assertion
30+
if (properties.Name.type !== 'title') throw new Error('Name is not a title');
31+
if (properties.Description.type !== 'rich_text')
32+
throw new Error('Description is not rich text');
33+
if (properties.Website.type !== 'url') throw new Error('Website is not a URL');
34+
if (properties['Working Since'].type !== 'date')
35+
throw new Error('Working Since is not a date');
36+
37+
if (page.icon?.type !== 'file') throw new Error('Logo is not a file');
38+
if (page.cover?.type !== 'file') throw new Error('Cover is not a file');
39+
40+
// Convert dates
41+
const dates = properties['Working Since'].date
42+
? convertNotionDates(properties['Working Since'].date)
43+
: { start: new Date(), end: null };
44+
45+
return {
46+
name: convertRichText(properties.Name.title) || '',
47+
description: convertRichText(properties.Description.rich_text) || 'Very mysterious!',
48+
website: properties.Website.url || undefined,
49+
dates,
50+
logo: page.icon.file.url,
51+
cover: page.cover.file.url
52+
};
53+
})
54+
.sort((a, b) => (b.dates.end ?? new Date()).getTime() - (a.dates.end ?? new Date()).getTime());
3655

3756
return { pinned, clients };
3857
};
@@ -65,6 +84,7 @@ export interface ClientItem {
6584
name: string;
6685
description: string;
6786
website?: string;
87+
dates: ReturnType<typeof convertNotionDates>;
6888

6989
logo?: string;
7090
cover?: string;

src/utils/notion.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { RichTextItemResponse } from '@notionhq/client/build/src/api-endpoints';
2+
3+
export type DateResponse = {
4+
start: string;
5+
end: string | null;
6+
};
7+
8+
export const convertNotionDates = (date: DateResponse) => {
9+
const start = new Date(date.start);
10+
const end = date.end ? new Date(date.end) : null;
11+
return { start, end };
12+
};
13+
14+
export const convertRichText = (text: Array<RichTextItemResponse> | undefined) => {
15+
if (!text) return null;
16+
return text.map((item) => item.plain_text).join('');
17+
};

0 commit comments

Comments
 (0)