added Card component
This commit is contained in:
parent
614bd04405
commit
943f36f76f
2 changed files with 118 additions and 24 deletions
71
frontend/src/components/Card.svelte
Normal file
71
frontend/src/components/Card.svelte
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
<script lang="ts">
|
||||||
|
type Props = {
|
||||||
|
children: any;
|
||||||
|
className: string;
|
||||||
|
href: string;
|
||||||
|
target?: string | null;
|
||||||
|
rel?: string | null;
|
||||||
|
color?: string | null;
|
||||||
|
};
|
||||||
|
let {
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
href,
|
||||||
|
target = "_blank",
|
||||||
|
rel = "noreferrer",
|
||||||
|
color = "purple",
|
||||||
|
}: Props = $props();
|
||||||
|
|
||||||
|
const accentColor = $derived(color?.trim() ? color : "purple");
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<a
|
||||||
|
{href}
|
||||||
|
{target}
|
||||||
|
{rel}
|
||||||
|
class={`${className} card`}
|
||||||
|
style:--primary-color={accentColor}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.card {
|
||||||
|
position: relative;
|
||||||
|
border: 1px solid rgb(255 255 255 / 5%);
|
||||||
|
border-radius: 1.5rem;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:after {
|
||||||
|
content: "";
|
||||||
|
height: 50px;
|
||||||
|
width: 1px;
|
||||||
|
position: absolute;
|
||||||
|
left: -1px;
|
||||||
|
top: 65%;
|
||||||
|
transition: top, opacity;
|
||||||
|
transition-duration: 600ms;
|
||||||
|
transition-timing-function: ease;
|
||||||
|
background: linear-gradient(
|
||||||
|
transparent,
|
||||||
|
var(--primary-color),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover:after {
|
||||||
|
top: 25%;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
.card {
|
||||||
|
width: calc(100% - 2rem);
|
||||||
|
margin: 0rem 1rem;
|
||||||
|
padding: 0.75rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { fetchMediaKit } from "../lib/api";
|
import { fetchMediaKit } from "../lib/api";
|
||||||
import type { MediaKit, Platform } from "../lib/types";
|
import type { MediaKit, Platform } from "../lib/types";
|
||||||
|
import Card from "../components/Card.svelte";
|
||||||
|
|
||||||
let data = $state<MediaKit | null>(null);
|
let data = $state<MediaKit | null>(null);
|
||||||
let error = $state("");
|
let error = $state("");
|
||||||
|
|
@ -19,11 +20,28 @@
|
||||||
let twitch = $derived(data?.twitch);
|
let twitch = $derived(data?.twitch);
|
||||||
// let twitchLogin = $derived(twitch?.login ?? "");
|
// let twitchLogin = $derived(twitch?.login ?? "");
|
||||||
|
|
||||||
let platformImageMap: Record<string, string> = {
|
type platformDecoType = {
|
||||||
twitch: "/images/logos/twitch.svg",
|
image: string;
|
||||||
youtube: "/images/logos/youtube.svg",
|
color?: string | null;
|
||||||
instagram: "/images/logos/instagram.svg",
|
};
|
||||||
tiktok: "/images/logos/tiktok.svg",
|
|
||||||
|
let platformImageMap: Record<string, platformDecoType> = {
|
||||||
|
twitch: {
|
||||||
|
image: "/images/logos/twitch.svg",
|
||||||
|
color: "#8E60F5",
|
||||||
|
},
|
||||||
|
youtube: {
|
||||||
|
image: "/images/logos/youtube.svg",
|
||||||
|
color: "#FF0000",
|
||||||
|
},
|
||||||
|
instagram: {
|
||||||
|
image: "/images/logos/instagram.svg",
|
||||||
|
color: "#E1306C",
|
||||||
|
},
|
||||||
|
tiktok: {
|
||||||
|
image: "/images/logos/tiktok.svg",
|
||||||
|
color: "#FFFFFF",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
function formatCount(value: number | undefined | null): string {
|
function formatCount(value: number | undefined | null): string {
|
||||||
if (value == null) return "—";
|
if (value == null) return "—";
|
||||||
|
|
@ -52,30 +70,33 @@
|
||||||
<div class="py-8 text-gray-500 dark:text-gray-400">Loading…</div>
|
<div class="py-8 text-gray-500 dark:text-gray-400">Loading…</div>
|
||||||
</main>
|
</main>
|
||||||
{:else}
|
{:else}
|
||||||
<main class="grid grid-cols-2 max-w-6xl mx-auto pt-20">
|
<main class="grid grid-cols-2 max-w-6xl mx-auto pt-20 pb-10">
|
||||||
<div class="">
|
<div class="">
|
||||||
<div class="px-5">
|
<div class="px-5">
|
||||||
|
<div class="flex justify-end items-start">
|
||||||
{#if content.profile_image_url}
|
{#if content.profile_image_url}
|
||||||
<img
|
<img
|
||||||
class="shrink-0 rounded-xl w-full object-cover shadow-cyan-300 shadow-lg"
|
class="shrink-0 rounded-xl object-cover shadow-cyan-300 shadow-lg"
|
||||||
src={content.profile_image_url}
|
src={content.profile_image_url}
|
||||||
alt={content.brand_name ?? "Profile image"}
|
alt={content.brand_name ?? "Profile image"}
|
||||||
width="300"
|
width="300"
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
<div class="mt-6 grid grid-cols-2 gap-4">
|
<div class="mt-6 grid grid-cols-2 gap-4">
|
||||||
<!-- Twitch -->
|
<!-- Twitch -->
|
||||||
<a
|
<Card
|
||||||
class="flex flex-col gap-1 rounded-2xl border border-gray-200 bg-neutral-50 p-5 transition-colors hover:border-violet-600 dark:border-zinc-800 dark:bg-neutral-900 dark:hover:border-violet-400"
|
className="flex flex-col gap-1 rounded-2xl border p-5 transition-colors border-zinc-800 bg-neutral-900"
|
||||||
href={`https://twitch.tv/${twitch?.login}`}
|
href={`https://twitch.tv/${twitch?.login}`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
|
color={platformImageMap["twitch"].color}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="flex flex-row justify-start items-start gap-3"
|
class="flex flex-row justify-start items-start gap-3"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={platformImageMap["twitch"]}
|
src={platformImageMap["twitch"].image}
|
||||||
alt="Twitch"
|
alt="Twitch"
|
||||||
width="40"
|
width="40"
|
||||||
/>
|
/>
|
||||||
|
|
@ -97,19 +118,20 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</Card>
|
||||||
{#each platforms as platform (platform.name)}
|
{#each platforms as platform (platform.name)}
|
||||||
<a
|
<Card
|
||||||
class="flex flex-col gap-1 rounded-2xl border border-gray-200 bg-neutral-50 p-5 transition-colors hover:border-violet-600 dark:border-zinc-800 dark:bg-neutral-900 dark:hover:border-violet-400"
|
className="flex flex-col gap-1 rounded-2xl border p-5 transition-colors border-zinc-800 bg-neutral-900"
|
||||||
href={platform.url}
|
href={platform.url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
|
color={platformImageMap[platform.name]?.color}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="flex flex-row justify-start items-start gap-3"
|
class="flex flex-row justify-start items-start gap-3"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={platformImageMap[platform.name]}
|
src={platformImageMap[platform.name].image}
|
||||||
alt="Twitch"
|
alt="Twitch"
|
||||||
width="48"
|
width="48"
|
||||||
/>
|
/>
|
||||||
|
|
@ -137,15 +159,16 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</Card>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 2nd column -->
|
||||||
<div class="">
|
<div class="">
|
||||||
<div class="border-cyan border-2 rounded-lg py-2 px-2">
|
<div class="border-cyan-300 border-2 rounded-lg translate-y-2">
|
||||||
<div
|
<div
|
||||||
class="-translate-x-20 px-5 py-5 text-4xl bg-cyan-300 text-black rounded-xl"
|
class="-translate-x-20 px-5 py-5 text-4xl bg-cyan-300 text-black rounded-xl -translate-y-2"
|
||||||
>
|
>
|
||||||
Hi there, I'm <br />
|
Hi there, I'm <br />
|
||||||
<b>RythonDev</b>
|
<b>RythonDev</b>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue