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

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>

View File

@@ -10,7 +10,7 @@
<div class="grid my-4 text-center ">
<h1 class="bts-h1">Sir Blob</h1>
<br>
<p class="h-fit text-2xl typewriter anim-typewriter">Projects, Games, API, and More</p>
<p class="h-fit text-2xl typewriter anim-typewriter">Projects, Games, API, and More!</p>
</div>
<div class="my-4 text-center flex-col">
<button type="button" class="mx-2 my-2 btn variant-ghost-tertiary">
@@ -22,7 +22,13 @@
</button>
<!-- <button type="button" class="mx-2 my-2 btn variant-ghost-warning">Projects</button>
<button type="button" class="mx-2 my-2 btn variant-ghost-success">TGS</button> -->
<!-- <button type="button" class="mx-2 my-2 btn variant-ghost-error">Models</button> -->
<button type="button" class="mx-2 my-2 btn variant-ghost-error">
<a
href="/hackathons"
rel="noreferrer">
Hackathons
</a>
</button>
<button type="button" class="mx-4 my-4 btn variant-ghost-secondary">
<a
href="https://github.com/SirBlobby"

View File

@@ -7,43 +7,120 @@
image?: string;
link?: string;
repo?: string;
date?: string;
devpost?: string;
hackathonName?: string;
university?: string;
location?: string;
year?: string;
tags?: string[];
featured?: boolean;
awards?: { track: string; place: string }[];
liveWarning?: boolean;
};
// Sample data — replace or enhance as you add real entries
const cards: Card[] = [
{
title: "QuickMap — Live Mapping",
image: "/hacks/fooddecisive.png",
title: "Food Decisive",
description:
"Realtime map-sharing tool built during the 48h MapHack. Streamlined tile sync and offline caching.",
image: "/src/lib/images/project-map.png",
link: "https://example.com/quickmap",
repo: "https://github.com/SirBlobby/quickmap",
date: "Aug 2024",
tags: ["JS", "PWA", "Maps"],
"Ever felt the indecisiveness of choosing what to eat? Don't fret! Decide your next bite with Food Decisive",
link: "https://fooddecisive.sirblob.co/",
repo: "https://github.com/SirBlobby/VTHacks-12",
devpost: "https://devpost.com/software/food-decisive",
hackathonName: "VTHacks 12",
university: "Virginia Tech",
location: "Blacksburg, VA",
year: "2024",
tags: ["AI", "Llama3.1", "Svelte", "Node.js"],
featured: false,
liveWarning: true
},
{
image: "/hacks/carbin.png",
title: "Carbin",
description:
"Encourage student participation in responsible waste management with smart bins that guide proper disposal.",
repo: "https://github.com/SirBlobby/patriotHacks2024",
devpost: "https://devpost.com/software/carbin",
hackathonName: "PatriotHacks 2024",
university: "George Mason University",
location: "Fairfax, VA",
year: "2024",
tags: ["AI", "Azure", "CloudConvert", "Python", "React", "TypeScript", "API"],
featured: true,
awards: [
{ track: "Save the World", place: "2nd Place" },
{ track: "Microsoft X Cloudforce", place: "2nd Place" }
]
},
{
title: "BlobChat — Minimal Chatbot",
image: "/hacks/patsafe.png",
title: "PatSafe",
description:
"A tiny chat UI and embeddable bot for community sites. Built with accessibility in mind.",
image: "/src/lib/images/project-chat.png",
repo: "https://github.com/SirBlobby/blobchat",
date: "Nov 2023",
tags: ["Svelte", "Accessibility"],
"Bridging the gap between doctors and patients for seamless post-discharge care",
link: "https://hoya-hax2025.vercel.app/",
repo: "https://github.com/SirBlobby/HoyaHax2025",
devpost: "https://devpost.com/software/patsafe",
hackathonName: "HoyaHax 2025",
university: "Georgetown University",
location: "Washington, D.C.",
year: "2025",
tags: ["Javascript", "Next.js", "React", "TypeScript", "LangChain", "OpenAI"],
},
{
title: "GameJam Runner",
title: "Fauxcall",
description:
"Competition runner for quick prototyping. Handles assets, scoring, and results publishing.",
image: "/src/lib/images/project-game.png",
link: "https://example.com/gamejam-runner",
date: "May 2025",
tags: ["Game", "Tooling"],
"This product is perfect for situations where you are walking at night and you feel unsafe from someone. Fauxcall lets users create a convincing fake phone call to deter potential attackers and provide a quick escape mechanism.",
link: "",
repo: "https://github.com/SirBlobby/HooHacks-12",
devpost: "https://devpost.com/software/fauxcall",
hackathonName: "HooHacks 2025",
university: "University of Virginia",
location: "Charlottesville, VA",
year: "2025",
tags: ["mongodb", "next.js", "python", "react", "sesame.com", "skeleton", "twilio"],
featured: false
},
{
image: "/hacks/drinkhappy.png",
title: "Drink Happy",
description:
"drinkhappy.tech is a gamified hydration wellness app that helps users track drinks, earn points for healthy choices, and compete with friends. It's powered by Gemini AI for smart drink recognition.",
link: "https://drinkhappy.tech",
repo: "https://github.com/SirBlobby/Bitcamp-2025",
devpost: "https://devpost.com/software/drink-happy",
hackathonName: "Bitcamp",
university: "University of Maryland",
location: "College Park, MD",
year: "2025",
tags: ["api", "auth0", "gemini", "github", "javascript", "mongodb", "nextjs", "react", "tailwind", "vercel"],
featured: false
},
{
image: "/hacks/roadcast.png",
title: "Roadcast",
description:
"Roadcast provides drivers with crash data and weather insights to choose safer routes home. The project combines historical crash data, weather feeds, and spatial analysis to surface hazardous areas and route-level safety recommendations.",
link: "https://roadcast.sirblob.co/",
repo: "https://github.com/SirBlobby/roadcast",
devpost: "https://devpost.com/software/roadcast",
hackathonName: "VTHacks 13",
university: "Virginia Tech",
location: "Blacksburg, VA",
year: "2025",
tags: ["react", "node.js", "python", "mongodb", "geospatial", "mapbox"],
featured: true,
liveWarning: true
}
];
// Sort cards to show featured first
$: sortedCards = [...cards].sort((a, b) => {
if (a.featured && !b.featured) return -1;
if (!a.featured && b.featured) return 1;
return 0;
});
</script>
<section class="container mx-auto py-12 px-4">
@@ -52,7 +129,7 @@
<div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 items-stretch"
>
{#each cards as c}
{#each sortedCards as c}
<div class="h-full">
<HackCard
title={c.title}
@@ -60,9 +137,15 @@
image={c.image}
link={c.link}
repo={c.repo}
date={c.date}
devpost={c.devpost}
hackathonName={c.hackathonName}
university={c.university}
location={c.location}
year={c.year}
tags={c.tags}
featured={c.featured}
awards={c.awards}
liveWarning={c.liveWarning}
/>
</div>
{/each}

BIN
static/hacks/carbin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
static/hacks/drinkhappy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
static/hacks/patsafe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
static/hacks/roadcast.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB