#201 encapsulate Top Packages on its own component use Airtable category top_package

This commit is contained in:
neil 2023-02-14 13:47:53 +08:00
parent 1299bf77a8
commit 26ff496eba
6 changed files with 124 additions and 54 deletions

View file

@ -0,0 +1,32 @@
<!-- home / discover / welcome page -->
<script lang="ts">
import '$appcss';
import ListAction from '@tea/ui/ListAction/ListAction.svelte';
import type { ListActionItem } from '@tea/ui/types';
import { packagesStore } from '$libs/stores';
let items: ListActionItem[];
packagesStore.subscribe((ps) => {
items = ps
.filter((p) => (p.categories || []).includes('top_packages'))
.map((pkg) => ({
title: pkg.full_name,
sub_title: pkg.version,
action_label: 'INSTALL',
image_url: pkg.thumb_image_url,
detail_url: `/packages/${pkg.slug}`
}));
});
const onSelectPackage = async (item:ListActionItem) => {
console.log(item);
}
</script>
<ListAction
title="Top packages this week"
mainCtaTitle="VIEW ALL SCRIPTS"
items={items}
onSelectItem={onSelectPackage}
/>

View file

@ -0,0 +1,49 @@
<!-- home / discover / welcome page -->
<script lang="ts">
import '$appcss';
import type { ListActionItem } from '@tea/ui/types';
import ListAction from '@tea/ui/ListAction/ListAction.svelte';
const items: ListActionItem[] = [
{
title: 'Script A',
sub_title: 'v 0.0.1',
image_url: '/images/bored-ape.png',
action_label: 'USE'
},
{
title: 'Script B',
sub_title: 'v 0.1.1',
image_url: '/images/bored-ape.png',
action_label: 'USE'
},
{
title: 'Script C',
sub_title: 'v 2.0.1',
image_url: '/images/bored-ape.png',
action_label: 'USE'
},
{
title: 'Script D',
sub_title: 'v 0.1.1',
image_url: '/images/bored-ape.png',
action_label: 'USE'
},
{
title: 'Script E',
sub_title: 'v 0.1.1',
image_url: '/images/bored-ape.png',
action_label: 'USE'
},
];
</script>
<ListAction
title="Top scripts this week"
mainCtaTitle="VIEW ALL SCRIPTS"
items={items}
onSelectItem={async (script) => {
console.log(script)
}}
/>

View file

@ -84,7 +84,6 @@ export async function getAllPosts(tag?: string): Promise<AirtablePost[]> {
nocache: 'true'
};
const posts = await apiGet<AirtablePost[]>('posts', queryParams);
console.log(posts);
return posts;
}

View file

@ -7,7 +7,8 @@
import News from '$components/News/News.svelte';
import HeaderCard from '@tea/ui/HeaderCard/HeaderCard.svelte';
import ListAction from '@tea/ui/ListAction/ListAction.svelte';
import TopPackages from '$components/top-packages/top-packages.svelte';
import TopScripts from '$components/top-scripts/top-scripts.svelte';
</script>
<div>
@ -26,7 +27,7 @@
articleTitle="What are packages?"
description="Collections of files aggregated to form larger frameworks & functions. Think Python or Node.js."
/>
<ListAction title="Top packages this week" mainCtaTitle="VIEW ALL PACKAGES" mainCtaLink="/packages"/>
<TopPackages />
</div>
<div>
<HeaderCard
@ -37,7 +38,7 @@
articleTitle="What are scripts?"
description="Invisible applications that chain packages together in order to perform cool actions on your computer."
/>
<ListAction title="Top scripts this week" mainCtaTitle="VIEW ALL SCRIPTS" />
<TopScripts/>
</div>
</section>
<PageHeader coverUrl="/images/headers/header_bg_1.png">TUTORIALS</PageHeader>

View file

@ -1,64 +1,45 @@
<script lang="ts">
import Button from '../Button/Button.svelte';
import ImgLoader from '../ImgLoader/ImgLoader.svelte';
import type { ListActionItem } from '../types';
export let title: string;
export let mainCtaTitle: string;
export let mainCtaLink = '/';
export let items: ListActionItem[];
export let onSelectItem = (item: ListActionItem) => console.log(item);
const onSelect = (item: ListActionItem) => {
if (onSelectItem) {
onSelectItem(item);
}
};
</script>
<section class="bg-black">
<header class="w-full border border-gray p-2 text-primary">{title}</header>
<ul class="border border-b-0 border-r-0 border-l-0 border-gray">
<li class="flex content-center border border-t-0 border-gray">
<figure class="m-2 w-10 bg-gray" />
<div class="flex flex-grow pt-4 leading-10">
<div class="text-sm">Homebrew</div>
<div class="pl-2 text-sm text-gray">ver 1.21</div>
</div>
<div class="m-2 w-28 border border-gray">
<Button>INSTALL</Button>
</div>
</li>
<li class="flex content-center border border-t-0 border-gray">
<figure class="m-2 w-10 bg-gray" />
<div class="flex flex-grow pt-4 leading-10">
<div class="text-sm">Homebrew</div>
<div class="pl-2 text-sm text-gray">ver 1.21</div>
</div>
<div class="m-2 w-28 border border-gray">
<Button>INSTALL</Button>
</div>
</li>
<li class="flex content-center border border-t-0 border-gray">
<figure class="m-2 w-10 bg-gray" />
<div class="flex flex-grow pt-4 leading-10">
<div class="text-sm">Homebrew</div>
<div class="pl-2 text-sm text-gray">ver 1.21</div>
</div>
<div class="m-2 w-28 border border-gray">
<Button>INSTALL</Button>
</div>
</li>
<li class="flex content-center border border-t-0 border-gray">
<figure class="m-2 w-10 bg-gray" />
<div class="flex flex-grow pt-4 leading-10">
<div class="text-sm">Homebrew</div>
<div class="pl-2 text-sm text-gray">ver 1.21</div>
</div>
<div class="m-2 w-28 border border-gray">
<Button>INSTALL</Button>
</div>
</li>
<li class="flex content-center border border-t-0 border-gray">
<figure class="m-2 w-10 bg-gray" />
<div class="flex flex-grow pt-4 leading-10">
<div class="text-sm">Homebrew</div>
<div class="pl-2 text-sm text-gray">ver 1.21</div>
</div>
<div class="m-2 w-28 border border-gray">
<Button>INSTALL</Button>
</div>
</li>
{#each items as item}
<li class="flex content-center border border-t-0 border-gray">
<figure class="m-2 w-10 bg-gray">
<img src={item.image_url} alt={item.title} />
</figure>
<div class="flex flex-grow pt-4 leading-10">
<div class="text-sm">{item.title}</div>
<div class="pl-2 text-sm text-gray">{item.sub_title}</div>
</div>
<div class="m-2 w-28 border border-gray">
{#if item.detail_url}
<a href={item.detail_url}>
<Button>{item.action_label}</Button>
</a>
{:else}
<Button onClick={() => onSelect(item)}>{item.action_label}</Button>
{/if}
</div>
</li>
{/each}
</ul>
<footer class="w-full border border-t-0 border-gray text-gray">
<a href={mainCtaLink} class="flex w-full">

View file

@ -104,3 +104,11 @@ export type Contributor = Pick<Developer, 'avatar_url' | 'login' | 'name'> & {
developer_id?: string;
contributions: number;
};
export interface ListActionItem {
title: string;
sub_title: string;
image_url: string;
action_label: string;
detail_url?: string;
}