Browse Source

feat(homepage): add latest repositories list view

add pure ui components:
 - add repo summary card
 - add repo summary list

add data wrapper components:
 - add repo recent

add repo rent to the homepage
master
DanConwayDev 2 years ago
parent
commit
a17b5fbc8f
No known key found for this signature in database
GPG Key ID: 68E15486D73F75E1
  1. BIN
      __snapshots__/repo-summary-card--loading.png
  2. BIN
      __snapshots__/repo-summary-card--long-and-no-spaces.png
  3. BIN
      __snapshots__/repo-summary-card--long-details.png
  4. BIN
      __snapshots__/repo-summary-card--no-details.png
  5. BIN
      __snapshots__/repo-summary-card--short-details.png
  6. 63
      __snapshots__/repo-summary-card.test.js.snap
  7. BIN
      __snapshots__/repo-summary-list--default.png
  8. BIN
      __snapshots__/repo-summary-list--empty.png
  9. BIN
      __snapshots__/repo-summary-list--loading.png
  10. BIN
      __snapshots__/repo-summary-list--no-title.png
  11. BIN
      __snapshots__/repo-summary-list--partially-loaded.png
  12. 151
      __snapshots__/repo-summary-list.test.js.snap
  13. 18
      src/lib/components/Repo.vectors.ts
  14. 26
      src/lib/components/RepoSummaryCard.stories.svelte
  15. 59
      src/lib/components/RepoSummaryCard.svelte
  16. 16
      src/lib/components/ReposFeatured.svelte
  17. 56
      src/lib/components/ReposSummaryList.stories.svelte
  18. 33
      src/lib/components/ReposSummaryList.svelte
  19. 32
      src/lib/wrappers/ReposRecent.svelte
  20. 4
      src/routes/+page.svelte

BIN
__snapshots__/repo-summary-card--loading.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
__snapshots__/repo-summary-card--long-and-no-spaces.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
__snapshots__/repo-summary-card--long-details.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
__snapshots__/repo-summary-card--no-details.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

BIN
__snapshots__/repo-summary-card--short-details.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

63
__snapshots__/repo-summary-card.test.js.snap

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Repo/Summary/Card Long Details test 1`] = `
<div class="card w-96 bg-primary text-primary-content s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<h2 class="card-title s-LKxYhcdFgLTA">
Long Name that goes on and on and on and on a...
</h2>
<p class="s-LKxYhcdFgLTA">
Lorem ipsum dolor sit amet, consectetur adipi...
</p>
</div>
</div>
`;
exports[`Repo/Summary/Card Long and No Spaces test 1`] = `
<div class="card w-96 bg-primary text-primary-content s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<h2 class="card-title s-LKxYhcdFgLTA">
LongNameLongNameLongNameLongNameLongNameLongN...
</h2>
<p class="s-LKxYhcdFgLTA">
LoremipsumLoremipsumLoremipsumLoremipsumLorem...
</p>
</div>
</div>
`;
exports[`Repo/Summary/Card No Details test 1`] = `
<div class="card w-96 bg-primary text-primary-content s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<h2 class="card-title s-LKxYhcdFgLTA">
Untitled
</h2>
<p class="s-LKxYhcdFgLTA">
</p>
</div>
</div>
`;
exports[`Repo/Summary/Card Short Details test 1`] = `
<div class="card w-96 bg-primary text-primary-content s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<h2 class="card-title s-LKxYhcdFgLTA">
Short Name
</h2>
<p class="s-LKxYhcdFgLTA">
short description
</p>
</div>
</div>
`;
exports[`Repo/Summary/Card loading test 1`] = `
<div class="card w-96 bg-neutral text-neutral-focus s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<div class="text-center s-LKxYhcdFgLTA">
<span class="loading loading-spinner loading-lg s-LKxYhcdFgLTA">
</span>
</div>
</div>
</div>
`;

BIN
__snapshots__/repo-summary-list--default.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
__snapshots__/repo-summary-list--empty.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
__snapshots__/repo-summary-list--loading.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
__snapshots__/repo-summary-list--no-title.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
__snapshots__/repo-summary-list--partially-loaded.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

151
__snapshots__/repo-summary-list.test.js.snap

@ -0,0 +1,151 @@ @@ -0,0 +1,151 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Repo/Summary/List Default test 1`] = `
<div class="space-y-5">
<div class="prose">
<h3>
Featured Repositories
</h3>
</div>
<div class="card w-96 bg-primary text-primary-content s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<h2 class="card-title s-LKxYhcdFgLTA">
Short Name
</h2>
<p class="s-LKxYhcdFgLTA">
short description
</p>
</div>
</div>
<div class="card w-96 bg-primary text-primary-content s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<h2 class="card-title s-LKxYhcdFgLTA">
Long Name that goes on and on and on and on a...
</h2>
<p class="s-LKxYhcdFgLTA">
Lorem ipsum dolor sit amet, consectetur adipi...
</p>
</div>
</div>
<div class="card w-96 bg-primary text-primary-content s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<h2 class="card-title s-LKxYhcdFgLTA">
LongNameLongNameLongNameLongNameLongNameLongN...
</h2>
<p class="s-LKxYhcdFgLTA">
LoremipsumLoremipsumLoremipsumLoremipsumLorem...
</p>
</div>
</div>
</div>
`;
exports[`Repo/Summary/List Empty test 1`] = `
<div class="space-y-5">
<div class="prose">
<h3>
Latest
</h3>
</div>
<p class="prose">
None
</p>
</div>
`;
exports[`Repo/Summary/List Loading test 1`] = `
<div class="space-y-5">
<div class="prose">
<h3>
Latest
</h3>
</div>
<div class="card w-96 bg-neutral text-neutral-focus s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<div class="text-center s-LKxYhcdFgLTA">
<span class="loading loading-spinner loading-lg s-LKxYhcdFgLTA">
</span>
</div>
</div>
</div>
<div class="card w-96 bg-neutral text-neutral-focus s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<div class="text-center s-LKxYhcdFgLTA">
<span class="loading loading-spinner loading-lg s-LKxYhcdFgLTA">
</span>
</div>
</div>
</div>
<div class="card w-96 bg-neutral text-neutral-focus s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<div class="text-center s-LKxYhcdFgLTA">
<span class="loading loading-spinner loading-lg s-LKxYhcdFgLTA">
</span>
</div>
</div>
</div>
</div>
`;
exports[`Repo/Summary/List No Title test 1`] = `
<div class="space-y-5">
<div class="card w-96 bg-primary text-primary-content s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<h2 class="card-title s-LKxYhcdFgLTA">
Short Name
</h2>
<p class="s-LKxYhcdFgLTA">
short description
</p>
</div>
</div>
<div class="card w-96 bg-primary text-primary-content s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<h2 class="card-title s-LKxYhcdFgLTA">
Long Name that goes on and on and on and on a...
</h2>
<p class="s-LKxYhcdFgLTA">
Lorem ipsum dolor sit amet, consectetur adipi...
</p>
</div>
</div>
</div>
`;
exports[`Repo/Summary/List Partially Loaded test 1`] = `
<div class="space-y-5">
<div class="prose">
<h3>
Latest
</h3>
</div>
<div class="card w-96 bg-primary text-primary-content s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<h2 class="card-title s-LKxYhcdFgLTA">
Short Name
</h2>
<p class="s-LKxYhcdFgLTA">
short description
</p>
</div>
</div>
<div class="card w-96 bg-primary text-primary-content s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<h2 class="card-title s-LKxYhcdFgLTA">
Long Name that goes on and on and on and on a...
</h2>
<p class="s-LKxYhcdFgLTA">
Lorem ipsum dolor sit amet, consectetur adipi...
</p>
</div>
</div>
<div class="card w-96 bg-neutral text-neutral-focus s-LKxYhcdFgLTA">
<div class="card-body s-LKxYhcdFgLTA">
<div class="text-center s-LKxYhcdFgLTA">
<span class="loading loading-spinner loading-lg s-LKxYhcdFgLTA">
</span>
</div>
</div>
</div>
</div>
`;

18
src/lib/components/Repo.vectors.ts

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
import type { Args as SummaryCardArgs } from "./RepoSummaryCard.svelte";
export let RepoSummaryCardArgsVectors = {
Short: {
name: "Short Name",
description: "short description",
} as SummaryCardArgs,
Long: {
name: "Long Name that goes on and on and on and on and on and on and on and on and on",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis quis nisl eget turpis congue molestie. Nulla vitae purus nec augue accumsan facilisis sed sed ligula. Vestibulum sed risus lacinia risus lacinia molestie. Ut lorem quam, consequat eget tempus in, rhoncus vel nunc. Duis efficitur a leo vel sodales. Nam id fermentum lacus. Etiam nec placerat velit. Praesent ac consectetur est. Aenean iaculis commodo enim.",
} as SummaryCardArgs,
LongNoSpaces: {
name: "LongNameLongNameLongNameLongNameLongNameLongNameLongNameLongName",
description:
"LoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsumLoremipsum>",
} as SummaryCardArgs,
};

26
src/lib/components/RepoSummaryCard.stories.svelte

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
<script lang="ts" context="module">
import type { Meta } from "@storybook/svelte";
import RepoSummaryCard from "./RepoSummaryCard.svelte";
import { Story, Template } from "@storybook/addon-svelte-csf";
import { RepoSummaryCardArgsVectors as vectors } from "./Repo.vectors";
export const meta: Meta<RepoSummaryCard> = {
title: "Repo/Summary/Card",
component: RepoSummaryCard,
tags: ["autodocs"],
};
</script>
<Template let:args>
<RepoSummaryCard {...args} />
</Template>
<Story name="Short Details" args={vectors.Short} />
<Story name="Long Details" args={vectors.Long} />
<Story name="Long and No Spaces" args={vectors.LongNoSpaces} />
<Story name="No Details" args={{}} />
<Story name="loading" args={{ loading: true }} />

59
src/lib/components/RepoSummaryCard.svelte

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
<script lang="ts" context="module">
export interface Args {
name: string;
description: string;
loading?: boolean;
}
export const defaults: Args = {
name: "",
description: "",
loading: false,
};
</script>
<script lang="ts">
import { slide } from "svelte/transition";
export let { name, description, loading } = defaults;
let short_name: string;
$: {
if (name.length > 45) short_name = name.slice(0, 45) + "...";
else if (name.length == 0) short_name = "Untitled";
else short_name = name;
}
$: short_descrption =
description.length > 50 ? description.slice(0, 45) + "..." : description;
</script>
{#if loading}
<div
transition:slide={{ duration: 50 }}
class="card w-96 bg-neutral text-neutral-focus"
>
<div class="card-body">
<div class="text-center">
<span class="loading loading-spinner loading-lg" />
</div>
</div>
</div>
{:else}
<div
transition:slide={{ duration: 50 }}
class="card w-96 bg-primary text-primary-content"
>
<div class="card-body">
<h2 class="card-title">{short_name}</h2>
<p>{short_descrption}</p>
</div>
</div>
{/if}
<style>
h2 {
display: inline-block;
}
p,
h2 {
word-wrap: break-word;
}
</style>

16
src/lib/components/ReposFeatured.svelte

@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
<div class="space-y-5">
<div class="prose">
<h3>Featured Repositories</h3>
</div>
{#each ["1", "2", "3"] as suffix}
<div class="card w-96 bg-primary text-primary-content">
<div class="card-body">
<h2 class="card-title">Placeholder Repo {suffix}</h2>
<p>Description of repository</p>
<div class="card-actions justify-end">
<button class="btn">Details</button>
</div>
</div>
</div>
{/each}
</div>

56
src/lib/components/ReposSummaryList.stories.svelte

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
<script lang="ts" context="module">
import type { Meta } from "@storybook/svelte";
import ReposSummaryList from "./ReposSummaryList.svelte";
import { Story, Template } from "@storybook/addon-svelte-csf";
import { RepoSummaryCardArgsVectors as vectors } from "./Repo.vectors";
export const meta: Meta<ReposSummaryList> = {
title: "Repo/Summary/List",
component: ReposSummaryList,
tags: ["autodocs"],
};
</script>
<Template let:args>
<ReposSummaryList {...args} />
</Template>
<Story
name="Default"
args={{
title: "Featured Repositories",
repos: [vectors.Short, vectors.Long, vectors.LongNoSpaces],
}}
/>
<Story
name="No Title"
args={{
repos: [vectors.Short, vectors.Long],
}}
/>
<Story
name="Empty"
args={{
title: "Latest",
repos: [],
}}
/>
<Story
name="Loading"
args={{
title: "Latest",
repos: [],
loading: true,
}}
/>
<Story
name="Partially Loaded"
args={{
title: "Latest",
repos: [vectors.Short, vectors.Long],
loading: true,
}}
/>

33
src/lib/components/ReposSummaryList.svelte

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
<script lang="ts">
import { fade } from "svelte/transition";
import { onMount } from "svelte";
import RepoSummaryCard, {
type Args as RepoSummaryCardArgs,
} from "$lib/components/RepoSummaryCard.svelte";
export let title: string = "";
export let repos: RepoSummaryCardArgs[] = [];
export let loading: boolean = false;
</script>
<div class="space-y-5">
{#if title.length > 0}
<div class="prose">
<h3>{title}</h3>
</div>
{/if}
{#if repos.length == 0 && !loading}
<p class="prose">None</p>
{/if}
{#each repos as { name, description }}
<RepoSummaryCard {name} {description} />
{/each}
{#if loading}
<RepoSummaryCard loading={true} />
{#if repos.length == 0}
<RepoSummaryCard loading={true} />
<RepoSummaryCard loading={true} />
{/if}
{/if}
</div>

32
src/lib/wrappers/ReposRecent.svelte

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
<script lang="ts">
import type { Args } from "$lib/components/RepoSummaryCard.svelte";
import ReposSummaryList from "$lib/components/ReposSummaryList.svelte";
import { ndk } from "$lib/stores/ndk";
export let limit: number = 5;
let repos: Args[] = [];
let loading: boolean = true;
let kind: number = 30017;
let sub = ndk.subscribe({
kinds: [kind],
limit,
});
sub.on("event", (event) => {
if (repos.length < limit) {
if (event.kind == kind)
repos = [
...repos,
{
name: event.tagValue("name") || "",
description: event.tagValue("description") || "",
},
];
} else if (loading == true) loading = false;
});
sub.on("eose", () => {
if (loading == true) loading = false;
});
</script>
<ReposSummaryList title="Latest Repositories" {repos} {loading} />

4
src/routes/+page.svelte

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
<script lang="ts">
import ReposFeatured from "$lib/components/ReposFeatured.svelte";
import ReposRecent from "$lib/wrappers/ReposRecent.svelte";
</script>
<div class="flex flex-row">
@ -13,6 +13,6 @@ @@ -13,6 +13,6 @@
</div>
</div>
<div class="hero h-[calc(100vh-4rem)] md:basis-1/2">
<ReposFeatured />
<ReposRecent />
</div>
</div>

Loading…
Cancel
Save