Hackathon Page

This commit is contained in:
2025-11-04 03:36:20 +00:00
parent b84eb2db3d
commit eca411fcf1
8 changed files with 216 additions and 82 deletions
+103 -58
View File
@@ -2,75 +2,133 @@
export let title: string = "Project Title";
export let description: string =
"Short project description that explains what the project does in one or two lines.";
export let image: string = "/src/lib/images/project.png";
export let image: string = "";
export let link: string = "";
export let repo: string = "";
export let date: string = "";
export let devpost: string = "";
export let hackathonName: string = "";
export let university: string = "";
export let location: string = "";
export let year: string = "";
export let tags: string[] = [];
export let featured: boolean = false;
export let awards: { track: string; place: string }[] = [];
export let liveWarning: boolean = false;
$: placeholderImage = `https://placehold.co/800x400/334155/94a3b8?text=${encodeURIComponent(title)}`;
$: displayImage = image || placeholderImage;
</script>
<article
class="card bg-surface-300 dark:bg-surface-700 rounded-xl overflow-hidden shadow-lg text-slate-900 dark:text-slate-100 min-h-[220px] flex flex-col"
class="card bg-surface-300 dark:bg-surface-700 rounded-xl overflow-hidden shadow-lg text-slate-900 dark:text-slate-100 flex flex-col relative"
>
<!-- small image badge in the top-left -->
<div
class="absolute -top-8 left-6 w-20 h-20 rounded-full overflow-hidden ring-4 ring-slate-200/30 bg-white dark:ring-white/5 dark:bg-slate-700"
>
<!-- Banner Image -->
<div class="w-full h-40 bg-slate-200 dark:bg-slate-800 overflow-hidden">
<img
src={image}
src={displayImage}
alt={title}
class="w-full h-full object-cover"
loading="lazy"
/>
</div>
<div class="p-6 pt-12 flex flex-col flex-1">
<div class="flex items-start justify-between gap-4">
<div class="max-w-[70%]">
<h3 class="text-xl md:text-2xl font-bold leading-tight fit-text-in-div">
{title}
</h3>
{#if date}
<p class="text-xs text-slate-500 dark:text-slate-400 mt-1">{date}</p>
{/if}
</div>
<!-- Content -->
<div class="p-6">
<!-- Title and Featured Badge -->
<div class="flex items-start justify-between gap-2">
<h3 class="text-xl md:text-2xl font-bold leading-tight">
{title}
</h3>
{#if featured}
<span
class="ml-auto inline-flex items-center text-xs font-semibold bg-amber-500 text-amber-900 px-2 py-1 rounded"
class="flex-shrink-0 inline-flex items-center text-xs font-semibold bg-amber-500 text-amber-900 px-2 py-1 rounded"
>Featured</span
>
{/if}
</div>
<p class="mt-4 text-sm text-slate-700 dark:text-slate-300 flex-grow">{description}</p>
<!-- Metadata -->
<div class="mt-2 flex flex-wrap gap-x-3 gap-y-1 text-xs text-slate-600 dark:text-slate-400">
{#if hackathonName}
<span class="font-semibold">{hackathonName}</span>
{/if}
{#if university}
<span>{university}</span>
{/if}
{#if location}
<span>{location}</span>
{/if}
{#if year}
<span>{year}</span>
{/if}
</div>
<div class="mt-4 flex items-center justify-between">
<div class="flex flex-wrap gap-2">
{#each tags as tag}
<span class="chip variant-filled text-xs">{tag}</span>
<!-- Awards Section -->
{#if awards && awards.length > 0}
<div class="mt-3 space-y-1">
{#each awards as award}
<div class="flex items-center gap-2 text-xs">
<span class="text-amber-600 dark:text-amber-400">🏆</span>
<span class="font-semibold text-slate-700 dark:text-slate-300">{award.place}</span>
<span class="text-slate-600 dark:text-slate-400"></span>
<span class="text-slate-600 dark:text-slate-400">{award.track}</span>
</div>
{/each}
</div>
{/if}
</div>
<div class="flex items-center gap-2">
{#if repo}
<a
href={repo}
target="_blank"
rel="noreferrer"
class="btn btn-sm variant-ghost">Repo</a
>
{/if}
{#if link}
<a
href={link}
target="_blank"
rel="noreferrer"
class="btn btn-sm btn-primary">Live</a
>
{/if}
<!-- Description -->
<div class="px-6 pb-4 flex-grow">
<p class="text-sm text-slate-700 dark:text-slate-300">{description}</p>
{#if liveWarning && link}
<div class="mt-3 flex items-start gap-2 text-xs text-amber-700 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20 p-2 rounded">
<span class="text-base">⚠️</span>
<span>Live site may not include all features from the original project.</span>
</div>
{/if}
</div>
<!-- Footer with tags and links -->
<div class="px-6 pb-6 pt-0 mt-auto">
<!-- Tags Row -->
{#if tags && tags.length > 0}
<div class="flex flex-wrap gap-2 mb-3">
{#each tags as tag}
<span class="chip variant-filled text-xs text-center whitespace-nowrap">{tag}</span>
{/each}
</div>
{/if}
<!-- Link Buttons Row -->
<div class="grid grid-cols-[repeat(auto-fit,minmax(80px,1fr))] gap-2">
{#if devpost}
<a
href={devpost}
target="_blank"
rel="noreferrer"
class="btn btn-sm variant-ghost w-full"
title="View on Devpost"
>
<span class="icon-[simple-icons--devpost]"></span>
</a>
{/if}
{#if repo}
<a
href={repo}
target="_blank"
rel="noreferrer"
class="btn btn-sm variant-ghost w-full">Repo</a
>
{/if}
{#if link}
<a
href={link}
target="_blank"
rel="noreferrer"
class="btn btn-sm variant-ghost-primary w-full">Live</a
>
{/if}
</div>
</div>
</article>
@@ -80,21 +138,8 @@
@apply w-full;
}
/* note: using project surface tokens (bg-surface-300 / dark:bg-surface-700)
removed the old .bg-card-alt fallback to avoid unused selector warnings */
/* fit text helper (copied from ProjectCard) */
.fit-text-in-div {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: block;
max-width: 14rem;
margin: 0;
}
/* ensure image badge doesn't collapse */
.ring-4 {
box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.08);
h3 {
word-break: break-word;
hyphens: auto;
}
</style>