mirror of
https://github.com/ivabus/gui
synced 2025-06-08 00:00:27 +03:00
#72 list installed packages
- added @tea/ui/MiniPackageCard reusable component
This commit is contained in:
parent
91d761b050
commit
1ff8137990
5 changed files with 151 additions and 3 deletions
|
@ -1,6 +1,39 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import '$appcss';
|
import '$appcss';
|
||||||
import Placeholder from '$components/Placeholder/Placeholder.svelte';
|
import type { GUIPackage } from '$libs/types';
|
||||||
|
import { PackageStates } from '$libs/types';
|
||||||
|
import PanelHeader from '@tea/ui/PanelHeader/PanelHeader.svelte';
|
||||||
|
import { packages as packagesStore } from '$libs/stores';
|
||||||
|
import MiniPackageCard from '@tea/ui/MiniPackageCard/MiniPackageCard.svelte';
|
||||||
|
import Preloader from '@tea/ui/Preloader/Preloader.svelte';
|
||||||
|
let packages: GUIPackage[] = [];
|
||||||
|
|
||||||
|
packagesStore.subscribe((v) => {
|
||||||
|
packages = v.filter((p) => p.state === PackageStates.INSTALLED);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Placeholder label="InstalledPackages" />
|
<PanelHeader title="My installs" ctaLabel="Check for updates >" ctaLink="#" />
|
||||||
|
|
||||||
|
<ul class="grid grid-cols-3 border border-r-0 border-gray bg-black">
|
||||||
|
{#if packages.length > 0}
|
||||||
|
{#each packages as pkg}
|
||||||
|
<div class="border border-t-0 border-l-0 border-gray p-4">
|
||||||
|
<MiniPackageCard
|
||||||
|
{pkg}
|
||||||
|
link={`/packages/${pkg.slug}`}
|
||||||
|
ctaLabel="DETAILS"
|
||||||
|
onClickCTA={async () => {
|
||||||
|
console.log('do something with:', pkg.full_name);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
{:else}
|
||||||
|
{#each Array(12) as _}
|
||||||
|
<section class="h-50 border border-gray p-4">
|
||||||
|
<Preloader />
|
||||||
|
</section>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
</ul>
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { PackageStates } from '../types';
|
||||||
|
|
||||||
const base = 'https://api.tea.xyz/v1';
|
const base = 'https://api.tea.xyz/v1';
|
||||||
|
|
||||||
async function get<T>(path: string, query?: { [key: string]: any }) {
|
async function get<T>(path: string, query?: { [key: string]: string }) {
|
||||||
const client = await getClient();
|
const client = await getClient();
|
||||||
const uri = join(base, path);
|
const uri = join(base, path);
|
||||||
const { data } = await client.get<T>(uri.toString(), {
|
const { data } = await client.get<T>(uri.toString(), {
|
||||||
|
|
46
packages/ui/src/MiniPackageCard/MiniPackageCard.stories.ts
Normal file
46
packages/ui/src/MiniPackageCard/MiniPackageCard.stories.ts
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import MiniPackageCard from './MiniPackageCard.svelte';
|
||||||
|
import type { Package } from '../types';
|
||||||
|
|
||||||
|
const SamplePkg: Package = {
|
||||||
|
slug: 'mesonbuild_com',
|
||||||
|
homepage: 'https://mesonbuild.com',
|
||||||
|
name: 'mesonbuild.com',
|
||||||
|
version: '0.63.3',
|
||||||
|
last_modified: '2022-10-06T15:45:08.000Z',
|
||||||
|
full_name: 'mesonbuild.com',
|
||||||
|
dl_count: 270745,
|
||||||
|
thumb_image_name: 'mesonbuild_com_option 1.jpg ',
|
||||||
|
maintainer: 'neilm',
|
||||||
|
desc: 'Fast and user friendly build system',
|
||||||
|
thumb_image_url: 'https://tea.xyz/Images/packages/mesonbuild_com.jpg',
|
||||||
|
installs: 0,
|
||||||
|
bottles: 23
|
||||||
|
};
|
||||||
|
|
||||||
|
// More on how to set up stories at: https://storybook.js.org/docs/7.0/svelte/writing-stories/introduction
|
||||||
|
export default {
|
||||||
|
title: 'Example/MiniPackageCard',
|
||||||
|
component: MiniPackageCard,
|
||||||
|
tags: ['docsPage'],
|
||||||
|
render: ({ pkg, link }: { pkg: Package; link: string }) => ({
|
||||||
|
Component: MiniPackageCard,
|
||||||
|
props: { pkg, link }
|
||||||
|
}),
|
||||||
|
argTypes: {
|
||||||
|
pkg: {
|
||||||
|
name: 'pkg',
|
||||||
|
description: 'type Package'
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
name: 'link'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// More on writing stories with args: https://storybook.js.org/docs/7.0/svelte/writing-stories/args
|
||||||
|
export const Example = {
|
||||||
|
args: {
|
||||||
|
pkg: SamplePkg,
|
||||||
|
link: '#'
|
||||||
|
}
|
||||||
|
};
|
68
packages/ui/src/MiniPackageCard/MiniPackageCard.svelte
Normal file
68
packages/ui/src/MiniPackageCard/MiniPackageCard.svelte
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<script type="ts">
|
||||||
|
import '../app.css';
|
||||||
|
import type { Package } from '../types';
|
||||||
|
import ImgLoader from '../ImgLoader/ImgLoader.svelte';
|
||||||
|
|
||||||
|
export let pkg: Package;
|
||||||
|
export let ctaLabel: string;
|
||||||
|
|
||||||
|
export let onClickCTA = () => {
|
||||||
|
console.log('do nothing');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section class="box-content flex h-24 w-full border border-gray font-sono">
|
||||||
|
<figure class="relative w-24">
|
||||||
|
<ImgLoader
|
||||||
|
class="pkg-image object-contain"
|
||||||
|
src={!pkg.thumb_image_url.includes('https://tea.xyz')
|
||||||
|
? 'https://tea.xyz/Images/package-thumb-nolabel4.jpg'
|
||||||
|
: pkg.thumb_image_url}
|
||||||
|
alt={pkg.name}
|
||||||
|
/>
|
||||||
|
<div class="absolute top-0 h-8 w-8 bg-accent text-center text-xs text-white">
|
||||||
|
<span class="leading-8">‹/›</span>
|
||||||
|
</div>
|
||||||
|
</figure>
|
||||||
|
<footer class="flex-grow px-2 text-white">
|
||||||
|
<h3 class="text-base uppercase">{pkg.name}</h3>
|
||||||
|
{#if pkg.maintainer}
|
||||||
|
<h4 class="text-xs">• {pkg.maintainer}</h4>
|
||||||
|
{/if}
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
<span class="text-xs text-gray"
|
||||||
|
>V {pkg.version} {pkg?.bottles ? `| ${pkg.bottles} bottles` : ''}</span
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button class="h-6 w-full font-machina text-xs" on:click={onClickCTA}>{ctaLabel}</button>
|
||||||
|
</footer>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
section {
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
transition: all 0.3s;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
border: 0.5px solid #ffffff;
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
min-width: 120px;
|
||||||
|
transition: 0.1s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #8000ff;
|
||||||
|
box-shadow: inset 0vw 0vw 0vw 0.223vw #1a1a1a !important;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -18,6 +18,7 @@ export interface Package {
|
||||||
dl_count: number;
|
dl_count: number;
|
||||||
installs: number;
|
installs: number;
|
||||||
reviews?: Review[];
|
reviews?: Review[];
|
||||||
|
bottles?: number; // TODO: where to get this?
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AirtablePost = {
|
export type AirtablePost = {
|
||||||
|
|
Loading…
Reference in a new issue