Merge pull request #155 from teaxyz/new-package-page-layout

#154 new package page layout
This commit is contained in:
Neil 2023-01-18 19:28:11 +08:00 committed by GitHub
commit 24999a44c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 121 additions and 16 deletions

View file

@ -1,6 +1,9 @@
<script lang="ts"> <script lang="ts">
import '$appcss'; import '$appcss';
import Placeholder from '$components/Placeholder/Placeholder.svelte'; import Placeholder from '$components/Placeholder/Placeholder.svelte';
export let arg1: string;
</script> </script>
<Placeholder label="Badges" /> <Placeholder label="Badges" />
<h1>{arg1 || 'tes'}</h1>

View file

@ -4,7 +4,6 @@
import type { Package, Bottle } from '@tea/ui/types'; import type { Package, Bottle } from '@tea/ui/types';
import Button from '@tea/ui/Button/Button.svelte'; import Button from '@tea/ui/Button/Button.svelte';
import StarRating from '@tea/ui/StarRating/StarRating.svelte'; import StarRating from '@tea/ui/StarRating/StarRating.svelte';
import Bottles from '@tea/ui/Bottles/Bottles.svelte';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { getPackageBottles } from '@api'; import { getPackageBottles } from '@api';
@ -33,20 +32,16 @@
<figure class="grow-1 w-1/3"> <figure class="grow-1 w-1/3">
<img width={260} src={pkg.thumb_image_url} alt={pkg.full_name} /> <img width={260} src={pkg.thumb_image_url} alt={pkg.full_name} />
</figure> </figure>
<article class="w-2/3 p-4"> <article class="w-2/3 p-4 pt-8">
<h3 class="text-5xl text-primary">{pkg.full_name}</h3> <h3 class="text-3xl text-primary">{pkg.full_name}</h3>
{#if pkg.maintainer} <h3>&#x2022; {pkg.maintainer || ''}{pkg.maintainer ? ' |' : ''} {bottles.length} bottles</h3>
<h3>* {pkg.maintainer}</h3>
{/if}
<div class="mt-4"> <div class="mt-4">
<StarRating maxRating={5} rating={packageRating} /> <StarRating maxRating={5} rating={packageRating} />
</div> </div>
<p class="mt-4 font-sono text-sm">{pkg.desc}</p> <p class="mt-4 font-sono text-sm">{pkg.desc}</p>
</article> </article>
</header> </header>
<section>
<Bottles {bottles} />
</section>
<footer class="flex h-20 border-t border-gray text-white"> <footer class="flex h-20 border-t border-gray text-white">
<input class="click-copy flex-grow bg-black pl-4" disabled value={copyValue} /> <input class="click-copy flex-grow bg-black pl-4" disabled value={copyValue} />
<Button class="w-16 border-0 border-l-2 text-sm" onClick={onCopy}>{copyButtonText}</Button> <Button class="w-16 border-0 border-l-2 text-sm" onClick={onCopy}>{copyButtonText}</Button>

View file

@ -0,0 +1,8 @@
<script lang="ts">
import type { Package } from '@tea/ui/types';
export let pkg: Package;
</script>
<section class="h-64 w-full">
<h1>{pkg.full_name}</h1>
</section>

View file

@ -1,8 +1,10 @@
<script lang="ts"> <script lang="ts">
export let coverUrl = ''; export let coverUrl = '';
let clazz = '';
export { clazz as class };
</script> </script>
<figure class="relative mb-8 h-32 w-full font-machina uppercase"> <figure class={`relative mb-8 h-32 w-full font-machina uppercase ${clazz}`}>
{#if coverUrl} {#if coverUrl}
<img src={coverUrl} class="absolute z-0 h-32 w-full object-cover" alt="cover" /> <img src={coverUrl} class="absolute z-0 h-32 w-full object-cover" alt="cover" />
{/if} {/if}

View file

@ -13,7 +13,7 @@
$: if ($navigating) view.scrollTop = 0; $: if ($navigating) view.scrollTop = 0;
afterNavigate(({ from, to }) => { afterNavigate(({ from, to }) => {
if (to?.route.id) { if (to?.route.id && from && from?.url) {
const nextPath = to.url.href.replace(to.url.origin, ''); const nextPath = to.url.href.replace(to.url.origin, '');
const fromPath = from?.url.href.replace(from.url.origin, ''); const fromPath = from?.url.href.replace(from.url.origin, '');
navStore.setNewPath(nextPath, fromPath || '/'); navStore.setNewPath(nextPath, fromPath || '/');

View file

@ -1,11 +1,18 @@
<script lang="ts"> <script lang="ts">
import '$appcss'; import '$appcss';
import { onMount } from 'svelte';
import PageHeader from '$components/PageHeader/PageHeader.svelte'; import PageHeader from '$components/PageHeader/PageHeader.svelte';
import { packagesReviewStore } from '$libs/stores'; import { packagesReviewStore } from '$libs/stores';
import PackageBanner from '$components/PackageBanner/PackageBanner.svelte'; import PackageBanner from '$components/PackageBanner/PackageBanner.svelte';
import PackageReviews from '$components/PackageReviews/PackageReviews.svelte'; import PackageReviews from '$components/PackageReviews/PackageReviews.svelte';
import type { Review } from '@tea/ui/types'; import type { Review, Bottle } from '@tea/ui/types';
import SuggestedPackages from '$components/SuggestedPackages/SuggestedPackages.svelte'; import SuggestedPackages from '$components/SuggestedPackages/SuggestedPackages.svelte';
import Tabs from '@tea/ui/Tabs/Tabs.svelte';
import type { Tab } from '@tea/ui/types';
import Badges from '$components/Badges/Badges.svelte';
import Bottles from '@tea/ui/Bottles/Bottles.svelte';
import { getPackageBottles } from '@api';
import PackageDetail from '$components/PackageDetail/PackageDetail.svelte';
/** @type {import('./$types').PageData} */ /** @type {import('./$types').PageData} */
export let data; export let data;
@ -17,11 +24,20 @@
let pkg: Package; let pkg: Package;
let reviews: Review[]; let reviews: Review[];
let bottles: Bottle[] = [];
let versions: string[] = [];
let tabs: Tab[] = [];
const setPkg = (pkgs: Package[]) => { const setPkg = (pkgs: Package[]) => {
const foundPackage = pkgs.find(({ slug }) => slug === data?.slug) as Package; const foundPackage = pkgs.find(({ slug }) => slug === data?.slug) as Package;
if (!pkg && foundPackage) { if (!pkg && foundPackage) {
pkg = foundPackage; pkg = foundPackage;
tabs.push({
label: 'details',
component: PackageDetail,
props: { pkg }
});
} }
if (!reviews && pkg) { if (!reviews && pkg) {
@ -33,17 +49,53 @@
packagesStore.subscribe(setPkg); packagesStore.subscribe(setPkg);
featuredPackages.subscribe(setPkg); featuredPackages.subscribe(setPkg);
onMount(async () => {
try {
const newBottles = await getPackageBottles(pkg.full_name);
const newVersion = newBottles.map((b) => b.version);
versions = [...new Set(newVersion)];
bottles.push(...newBottles);
console.log('sync tabs:', versions);
tabs = [
...tabs,
{
label: `versions (${versions.length || 0})`,
component: Bottles,
props: {
bottles
}
}
];
console.log(tabs);
} catch (err) {
console.error(err);
}
});
</script> </script>
<div> <div>
<PageHeader>{pkg.full_name}</PageHeader> <PageHeader coverUrl={pkg.thumb_image_url}>{pkg.full_name}</PageHeader>
<section> <section>
<PackageBanner {pkg} /> <PackageBanner {pkg} />
</section> </section>
<section class="mt-8">
<PackageReviews reviews={reviews || []} /> <section class="mt-8 flex gap-8">
<div class="w-2/3 bg-black">
<Tabs {tabs} />
</div>
<div class="h-64 w-1/3 bg-gray">metas</div>
</section> </section>
<PageHeader class="mt-8" coverUrl="/images/headers/header_bg_1.png">SNIPPETS</PageHeader>
<section class="mt-8 h-64 bg-gray">snippets</section>
<!-- <section class="mt-8">
<PackageReviews reviews={reviews || []} />
</section> -->
{#if pkg} {#if pkg}
<PageHeader class="mt-8" coverUrl="/images/headers/header_bg_1.png"
>YOU MAY ALSO LIKE...</PageHeader
>
<section class="mt-8"> <section class="mt-8">
<SuggestedPackages {pkg} /> <SuggestedPackages {pkg} />
</section> </section>

View file

@ -9,7 +9,7 @@
</script> </script>
<button <button
type="button font-sans" type="button"
class={`w-full p-2 font-machina text-gray ${clazz} ${active ? 'active' : ''}`} class={`w-full p-2 font-machina text-gray ${clazz} ${active ? 'active' : ''}`}
on:click={() => onClick && onClick()} on:click={() => onClick && onClick()}
> >

View file

@ -0,0 +1,36 @@
<script lang="ts">
import type { Tab } from '../types';
import { onMount } from 'svelte';
import Button from '../Button/Button.svelte';
export let tabs: Tab[] = [];
let active: string;
onMount(() => {
if (tabs.length) {
active = tabs[0].label;
}
});
console.log('t', tabs);
</script>
<section class="relative h-auto border border-gray">
<menu class="flex border border-gray">
{#each tabs as tab}
<div class="border border-y-0 border-l-0 border-gray text-white">
<Button onClick={() => (active = tab.label)}>
<span class={tab.label === active ? 'text-white' : ''}>{tab.label}</span>
</Button>
</div>
{/each}
</menu>
{#each tabs as tab}
{#if tab.label === active}
<svelte:component this={tab.component} {...tab.props} />
{/if}
{/each}
</section>

View file

@ -1,3 +1,4 @@
import type { ComponentType } from 'svelte';
export interface Review { export interface Review {
title: string; title: string;
comment: string; comment: string;
@ -50,3 +51,11 @@ export type Bottle = {
arch: string; arch: string;
version: string; version: string;
}; };
export type Tab = {
label: string;
props?: {
[key: string]: any;
};
component: ComponentType;
};