feat: enhance login page with FAQ section and improved styling

This commit is contained in:
2026-01-29 23:40:48 -06:00
parent fa28f13a45
commit 47b4f3315f
4 changed files with 111 additions and 14 deletions
+3
View File
@@ -5,6 +5,7 @@
"": { "": {
"name": "banner-web", "name": "banner-web",
"dependencies": { "dependencies": {
"@icons-pack/svelte-simple-icons": "^6.5.0",
"d3-scale": "^4.0.2", "d3-scale": "^4.0.2",
"d3-shape": "^3.2.0", "d3-shape": "^3.2.0",
"d3-time-format": "^4.1.0", "d3-time-format": "^4.1.0",
@@ -129,6 +130,8 @@
"@fontsource-variable/inter": ["@fontsource-variable/inter@5.2.8", "", {}, "sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ=="], "@fontsource-variable/inter": ["@fontsource-variable/inter@5.2.8", "", {}, "sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ=="],
"@icons-pack/svelte-simple-icons": ["@icons-pack/svelte-simple-icons@6.5.0", "", { "peerDependencies": { "@sveltejs/kit": "^2.5.0", "svelte": "^4.2.0 || ^5.0.0" } }, "sha512-Xj3PTioiV3TJ1NTKsXY95NFG8FUqw90oeyDZIlslWHs1KkuCheu1HOPrlHb0/IM0b4cldPgx/0TldzxzBlM8Cw=="],
"@internationalized/date": ["@internationalized/date@3.10.1", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-oJrXtQiAXLvT9clCf1K4kxp3eKsQhIaZqxEyowkBcsvZDdZkbWrVmnGknxs5flTD0VGsxrxKgBCZty1EzoiMzA=="], "@internationalized/date": ["@internationalized/date@3.10.1", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-oJrXtQiAXLvT9clCf1K4kxp3eKsQhIaZqxEyowkBcsvZDdZkbWrVmnGknxs5flTD0VGsxrxKgBCZty1EzoiMzA=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
+1
View File
@@ -36,6 +36,7 @@
"vitest": "^3.0.5" "vitest": "^3.0.5"
}, },
"dependencies": { "dependencies": {
"@icons-pack/svelte-simple-icons": "^6.5.0",
"d3-scale": "^4.0.2", "d3-scale": "^4.0.2",
"d3-shape": "^3.2.0", "d3-shape": "^3.2.0",
"d3-time-format": "^4.1.0", "d3-time-format": "^4.1.0",
+24
View File
@@ -55,6 +55,8 @@
--color-status-orange: var(--status-orange); --color-status-orange: var(--status-orange);
--color-status-gray: var(--status-gray); --color-status-gray: var(--status-gray);
--font-sans: "Inter Variable", ui-sans-serif, system-ui, sans-serif; --font-sans: "Inter Variable", ui-sans-serif, system-ui, sans-serif;
--animate-accordion-down: accordion-down 200ms ease-out;
--animate-accordion-up: accordion-up 200ms ease-out;
} }
body { body {
@@ -198,6 +200,28 @@ body::-webkit-scrollbar {
background: rgba(255, 255, 255, 0.4); background: rgba(255, 255, 255, 0.4);
} }
@keyframes accordion-down {
from {
height: 0;
opacity: 0;
}
to {
height: var(--bits-accordion-content-height);
opacity: 1;
}
}
@keyframes accordion-up {
from {
height: var(--bits-accordion-content-height);
opacity: 1;
}
to {
height: 0;
opacity: 0;
}
}
@keyframes pulse { @keyframes pulse {
0%, 0%,
100% { 100% {
+83 -14
View File
@@ -1,18 +1,87 @@
<script lang="ts"> <script lang="ts">
import { authStore } from "$lib/auth.svelte"; import { authStore } from "$lib/auth.svelte";
import { LogIn } from "@lucide/svelte"; import SiDiscord from "@icons-pack/svelte-simple-icons/icons/SiDiscord";
import { ChevronDown } from "@lucide/svelte";
import { Accordion } from "bits-ui";
const faqItems = [
{
value: "what",
question: "What does this do?",
answer: "Banner monitors UTSA course availability in real-time. Get notified on Discord when seats open up in the classes you need, so you never miss a registration window.",
},
{
value: "why-discord",
question: "Why sign in with Discord?",
answer: "Banner delivers notifications through a Discord bot. Signing in with Discord lets us link your account to send you alerts directly, and lets you manage your watchlist from the web dashboard.",
},
{
value: "data",
question: "What data do you access?",
answer: "We only request your Discord username and avatar. We don't read your messages, join servers on your behalf, or access any other Discord data.",
},
{
value: "official",
question: "Is this an official UTSA tool?",
answer: "No. Banner is an independent, community-built project. It is not affiliated with, endorsed by, or maintained by UTSA or Ellucian.",
},
];
</script> </script>
<div class="flex flex-1 items-center justify-center pb-14"> <div class="flex flex-1 items-center justify-center px-4 pb-14">
<div class="w-full max-w-sm space-y-6 text-center"> <div class="w-full max-w-md space-y-8">
<h1 class="text-3xl font-bold">Sign In</h1> <!-- Sign-in card -->
<p class="text-muted-foreground">Sign in with your Discord account to continue.</p> <div
<button class="rounded-xl border border-border bg-card p-8 text-center shadow-sm"
onclick={() => authStore.login()} >
class="inline-flex w-full items-center justify-center gap-2 rounded-lg bg-[#5865F2] px-6 py-3 text-lg font-semibold text-white transition-colors hover:bg-[#4752C4]" <p class="text-sm text-muted-foreground">
> Sign in to manage your watchlist and notifications.
<LogIn size={20} /> </p>
Sign in with Discord
</button> <button
</div> onclick={() => authStore.login()}
class="mt-6 inline-flex w-full items-center justify-center gap-2.5 rounded-lg bg-[#5865F2] px-6 py-3 text-base font-semibold text-white shadow-sm transition-colors hover:bg-[#4752C4] active:bg-[#3C45A5]"
>
<SiDiscord size={20} color="white" />
Sign in with Discord
</button>
</div>
<!-- FAQ section -->
<div class="space-y-3">
<h2
class="text-center text-xs font-medium uppercase tracking-widest text-muted-foreground"
>
Frequently Asked Questions
</h2>
<Accordion.Root type="single">
{#each faqItems as item (item.value)}
<Accordion.Item
value={item.value}
class="border-b border-border last:border-b-0"
>
<Accordion.Header>
<Accordion.Trigger
class="group flex w-full items-center justify-between py-3 text-left text-sm font-medium text-foreground/80 transition-colors hover:text-foreground"
>
{item.question}
<ChevronDown
size={16}
class="shrink-0 text-muted-foreground/50 transition-transform duration-200 group-data-[state=open]:rotate-180"
/>
</Accordion.Trigger>
</Accordion.Header>
<Accordion.Content
class="overflow-hidden text-sm leading-relaxed text-muted-foreground/70 data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
>
<div class="pb-3">
{item.answer}
</div>
</Accordion.Content>
</Accordion.Item>
{/each}
</Accordion.Root>
</div>
</div>
</div> </div>