Hackathon Page
This commit is contained in:
@@ -2,75 +2,133 @@
|
|||||||
export let title: string = "Project Title";
|
export let title: string = "Project Title";
|
||||||
export let description: string =
|
export let description: string =
|
||||||
"Short project description that explains what the project does in one or two lines.";
|
"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 link: string = "";
|
||||||
export let repo: 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 tags: string[] = [];
|
||||||
export let featured: boolean = false;
|
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>
|
</script>
|
||||||
|
|
||||||
<article
|
<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 -->
|
<!-- Banner Image -->
|
||||||
<div
|
<div class="w-full h-40 bg-slate-200 dark:bg-slate-800 overflow-hidden">
|
||||||
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"
|
|
||||||
>
|
|
||||||
<img
|
<img
|
||||||
src={image}
|
src={displayImage}
|
||||||
alt={title}
|
alt={title}
|
||||||
class="w-full h-full object-cover"
|
class="w-full h-full object-cover"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-6 pt-12 flex flex-col flex-1">
|
<!-- Content -->
|
||||||
<div class="flex items-start justify-between gap-4">
|
<div class="p-6">
|
||||||
<div class="max-w-[70%]">
|
<!-- Title and Featured Badge -->
|
||||||
<h3 class="text-xl md:text-2xl font-bold leading-tight fit-text-in-div">
|
<div class="flex items-start justify-between gap-2">
|
||||||
{title}
|
<h3 class="text-xl md:text-2xl font-bold leading-tight">
|
||||||
</h3>
|
{title}
|
||||||
{#if date}
|
</h3>
|
||||||
<p class="text-xs text-slate-500 dark:text-slate-400 mt-1">{date}</p>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if featured}
|
{#if featured}
|
||||||
<span
|
<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
|
>Featured</span
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</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">
|
<!-- Awards Section -->
|
||||||
<div class="flex flex-wrap gap-2">
|
{#if awards && awards.length > 0}
|
||||||
{#each tags as tag}
|
<div class="mt-3 space-y-1">
|
||||||
<span class="chip variant-filled text-xs">{tag}</span>
|
{#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}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center gap-2">
|
<!-- Description -->
|
||||||
{#if repo}
|
<div class="px-6 pb-4 flex-grow">
|
||||||
<a
|
<p class="text-sm text-slate-700 dark:text-slate-300">{description}</p>
|
||||||
href={repo}
|
|
||||||
target="_blank"
|
{#if liveWarning && link}
|
||||||
rel="noreferrer"
|
<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">
|
||||||
class="btn btn-sm variant-ghost">Repo</a
|
<span class="text-base">⚠️</span>
|
||||||
>
|
<span>Live site may not include all features from the original project.</span>
|
||||||
{/if}
|
|
||||||
{#if link}
|
|
||||||
<a
|
|
||||||
href={link}
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
class="btn btn-sm btn-primary">Live</a
|
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
@@ -80,21 +138,8 @@
|
|||||||
@apply w-full;
|
@apply w-full;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* note: using project surface tokens (bg-surface-300 / dark:bg-surface-700)
|
h3 {
|
||||||
removed the old .bg-card-alt fallback to avoid unused selector warnings */
|
word-break: break-word;
|
||||||
|
hyphens: auto;
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<div class="grid my-4 text-center ">
|
<div class="grid my-4 text-center ">
|
||||||
<h1 class="bts-h1">Sir Blob</h1>
|
<h1 class="bts-h1">Sir Blob</h1>
|
||||||
<br>
|
<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>
|
||||||
<div class="my-4 text-center flex-col">
|
<div class="my-4 text-center flex-col">
|
||||||
<button type="button" class="mx-2 my-2 btn variant-ghost-tertiary">
|
<button type="button" class="mx-2 my-2 btn variant-ghost-tertiary">
|
||||||
@@ -22,7 +22,13 @@
|
|||||||
</button>
|
</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-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-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">
|
<button type="button" class="mx-4 my-4 btn variant-ghost-secondary">
|
||||||
<a
|
<a
|
||||||
href="https://github.com/SirBlobby"
|
href="https://github.com/SirBlobby"
|
||||||
|
|||||||
@@ -7,43 +7,120 @@
|
|||||||
image?: string;
|
image?: string;
|
||||||
link?: string;
|
link?: string;
|
||||||
repo?: string;
|
repo?: string;
|
||||||
date?: string;
|
devpost?: string;
|
||||||
|
hackathonName?: string;
|
||||||
|
university?: string;
|
||||||
|
location?: string;
|
||||||
|
year?: string;
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
featured?: boolean;
|
featured?: boolean;
|
||||||
|
awards?: { track: string; place: string }[];
|
||||||
|
liveWarning?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sample data — replace or enhance as you add real entries
|
// Sample data — replace or enhance as you add real entries
|
||||||
const cards: Card[] = [
|
const cards: Card[] = [
|
||||||
{
|
{
|
||||||
title: "QuickMap — Live Mapping",
|
image: "/hacks/fooddecisive.png",
|
||||||
|
title: "Food Decisive",
|
||||||
description:
|
description:
|
||||||
"Realtime map-sharing tool built during the 48h MapHack. Streamlined tile sync and offline caching.",
|
"Ever felt the indecisiveness of choosing what to eat? Don't fret! Decide your next bite with Food Decisive",
|
||||||
image: "/src/lib/images/project-map.png",
|
link: "https://fooddecisive.sirblob.co/",
|
||||||
link: "https://example.com/quickmap",
|
repo: "https://github.com/SirBlobby/VTHacks-12",
|
||||||
repo: "https://github.com/SirBlobby/quickmap",
|
devpost: "https://devpost.com/software/food-decisive",
|
||||||
date: "Aug 2024",
|
hackathonName: "VTHacks 12",
|
||||||
tags: ["JS", "PWA", "Maps"],
|
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,
|
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:
|
description:
|
||||||
"A tiny chat UI and embeddable bot for community sites. Built with accessibility in mind.",
|
"Bridging the gap between doctors and patients for seamless post-discharge care",
|
||||||
image: "/src/lib/images/project-chat.png",
|
link: "https://hoya-hax2025.vercel.app/",
|
||||||
repo: "https://github.com/SirBlobby/blobchat",
|
repo: "https://github.com/SirBlobby/HoyaHax2025",
|
||||||
date: "Nov 2023",
|
devpost: "https://devpost.com/software/patsafe",
|
||||||
tags: ["Svelte", "Accessibility"],
|
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:
|
description:
|
||||||
"Competition runner for quick prototyping. Handles assets, scoring, and results publishing.",
|
"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.",
|
||||||
image: "/src/lib/images/project-game.png",
|
link: "",
|
||||||
link: "https://example.com/gamejam-runner",
|
repo: "https://github.com/SirBlobby/HooHacks-12",
|
||||||
date: "May 2025",
|
devpost: "https://devpost.com/software/fauxcall",
|
||||||
tags: ["Game", "Tooling"],
|
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>
|
</script>
|
||||||
|
|
||||||
<section class="container mx-auto py-12 px-4">
|
<section class="container mx-auto py-12 px-4">
|
||||||
@@ -52,7 +129,7 @@
|
|||||||
<div
|
<div
|
||||||
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 items-stretch"
|
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">
|
<div class="h-full">
|
||||||
<HackCard
|
<HackCard
|
||||||
title={c.title}
|
title={c.title}
|
||||||
@@ -60,9 +137,15 @@
|
|||||||
image={c.image}
|
image={c.image}
|
||||||
link={c.link}
|
link={c.link}
|
||||||
repo={c.repo}
|
repo={c.repo}
|
||||||
date={c.date}
|
devpost={c.devpost}
|
||||||
|
hackathonName={c.hackathonName}
|
||||||
|
university={c.university}
|
||||||
|
location={c.location}
|
||||||
|
year={c.year}
|
||||||
tags={c.tags}
|
tags={c.tags}
|
||||||
featured={c.featured}
|
featured={c.featured}
|
||||||
|
awards={c.awards}
|
||||||
|
liveWarning={c.liveWarning}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
BIN
static/hacks/carbin.png
Normal file
BIN
static/hacks/carbin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
BIN
static/hacks/drinkhappy.png
Normal file
BIN
static/hacks/drinkhappy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 474 KiB |
BIN
static/hacks/fooddecisive.png
Normal file
BIN
static/hacks/fooddecisive.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
BIN
static/hacks/patsafe.png
Normal file
BIN
static/hacks/patsafe.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
static/hacks/roadcast.png
Normal file
BIN
static/hacks/roadcast.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
Reference in New Issue
Block a user