Quality of life update & package migrations. Use Vercel as default adapter (#67)
* Update all packages * Manual migration to SkeletonUI v4.8.0. Event elements has breaking tabs underline highlight * Remove unused dependencies & Let Prettier clean everything * Minor misc styling update
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
inline-block rounded-md border-none px-4
|
||||
py-2 text-white transition-all
|
||||
duration-200 ease-out
|
||||
hover:shadow-xl hover:scale-105"
|
||||
hover:scale-105 hover:shadow-xl"
|
||||
{onclick}
|
||||
>
|
||||
{@render children()}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script>
|
||||
let { href = "https://www.example.com", children } = $props();
|
||||
let { href = 'https://www.example.com', children } = $props();
|
||||
</script>
|
||||
|
||||
<a {href} target="_blank" rel="noopener noreferrer" class="underline">
|
||||
{@render children()}
|
||||
{@render children()}
|
||||
</a>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script>
|
||||
// NOTE: I think there could be a better way to do this
|
||||
// NOTE: I think there could be a better way to do this
|
||||
import { PortableText } from '@portabletext/svelte';
|
||||
let { value } = $props();
|
||||
</script>
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<script lang="ts">
|
||||
// Reference: https://github.com/skeletonlabs/skeleton/blob/main/packages/skeleton-svelte/src/components/Avatar/Avatar.svelte
|
||||
import { Avatar } from '@skeletonlabs/skeleton-svelte';
|
||||
// Note: size, font, etc., are styled with TailwindCSS classes
|
||||
let { name, size, src }: {name: string, size: string, src: string} = $props();
|
||||
</script>
|
||||
|
||||
<Avatar
|
||||
{name}
|
||||
{src}
|
||||
font={"text-xl text-ecsess-black"}
|
||||
{size}
|
||||
rounded={"rounded-full"}
|
||||
background="bg-ecsess-400"
|
||||
imageBase="object-cover w-full h-full"
|
||||
/>
|
||||
23
src/components/council/CouncilAvatar.svelte
Normal file
23
src/components/council/CouncilAvatar.svelte
Normal file
@@ -0,0 +1,23 @@
|
||||
<script lang="ts">
|
||||
// Reference: https://github.com/skeletonlabs/skeleton/tree/88844ffb67b7c9553c5245dd6d70146a3d6b8932/packages/skeleton-svelte/src/components/avatar
|
||||
import { Avatar } from '@skeletonlabs/skeleton-svelte';
|
||||
let { name, src }: { name: string; src: string } = $props();
|
||||
|
||||
function getInitials(name: string): string {
|
||||
const words = name.trim().split(/\s+/);
|
||||
return words
|
||||
.slice(0, 5)
|
||||
.map((word) => word.charAt(0).toUpperCase())
|
||||
.join('');
|
||||
}
|
||||
</script>
|
||||
|
||||
<Avatar class="size-26 md:size-32">
|
||||
<Avatar.Image {src} class="h-full w-full rounded-full object-cover" />
|
||||
|
||||
<Avatar.Fallback>
|
||||
<div class="bg-ecsess-400 flex h-full w-full items-center justify-center rounded-full">
|
||||
<span class="text-ecsess-black text-xl font-bold"> {getInitials(name)} </span>
|
||||
</div>
|
||||
</Avatar.Fallback>
|
||||
</Avatar>
|
||||
@@ -1,17 +1,17 @@
|
||||
<script>
|
||||
let { onViewProfile, name, position, image } = $props();
|
||||
import Button from 'components/Button.svelte';
|
||||
import Avatar from 'components/council/Avatar.svelte';
|
||||
import CouncilAvatar from 'components/council/CouncilAvatar.svelte';
|
||||
</script>
|
||||
|
||||
<div class="text-ecsess-100 flex max-w-md items-center gap-6 p-3">
|
||||
<!-- Profile picture -->
|
||||
<div>
|
||||
<Avatar {name} size={"size-26 md:size-32"} src={image}/>
|
||||
</div>
|
||||
<div>
|
||||
<CouncilAvatar {name} src={image} />
|
||||
</div>
|
||||
<div class="text-left">
|
||||
<div class="text-xl md:text-2xl font-bold">{name}</div>
|
||||
<div class="text-sm md:text-base text-ecsess-200 mb-2 italic">{position}</div>
|
||||
<div class="text-xl font-bold md:text-2xl">{name}</div>
|
||||
<div class="text-ecsess-200 mb-2 text-sm italic md:text-base">{position}</div>
|
||||
<Button onclick={onViewProfile}>View Profile</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="text-ecsess-800 m-4 flex h-[275px] max-w-[564px]
|
||||
items-center gap-3 rounded-md border-transparent bg-transparent
|
||||
bg-gradient-to-br from-ecsess-50 to-ecsess-300 p-6"
|
||||
class="text-ecsess-800 from-ecsess-50 to-ecsess-300 m-4 flex
|
||||
h-70 max-w-142 items-center gap-3 rounded-md
|
||||
border-transparent bg-transparent bg-linear-to-br p-6"
|
||||
transition:slide
|
||||
>
|
||||
<!-- AVATAR -->
|
||||
@@ -24,7 +24,7 @@
|
||||
<p class="text-2xl font-bold lg:text-3xl">{name}</p>
|
||||
<p class="text-base italic">{position}</p>
|
||||
</div>
|
||||
<hr class="hr border-ecsess-600 border-1 border-dashed" />
|
||||
<hr class="hr border-ecsess-600 border border-dashed" />
|
||||
<div class="my-2 text-left">
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
|
||||
<!-- Gradient overlay -->
|
||||
<div
|
||||
class="absolute inset-0 bg-gradient-to-b from-transparent via-ecsess-800/30 to-ecsess-950"
|
||||
class="via-ecsess-800/30 to-ecsess-950 absolute inset-0 bg-gradient-to-b from-transparent"
|
||||
></div>
|
||||
|
||||
<!-- Badges -->
|
||||
@@ -139,9 +139,7 @@
|
||||
<div class="flex flex-1 flex-col p-6">
|
||||
<!-- Description -->
|
||||
{#if eventDescription}
|
||||
<div
|
||||
class="text-ecsess-100 mb-6 line-clamp-5"
|
||||
>
|
||||
<div class="text-ecsess-100 mb-6 line-clamp-5">
|
||||
<RichText value={eventDescription} />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
<script>
|
||||
import { Tabs } from '@skeletonlabs/skeleton-svelte';
|
||||
let { value, children } = $props();
|
||||
</script>
|
||||
|
||||
<Tabs.Control
|
||||
{value}
|
||||
classes="hover:border-b-ecsess-200 border-b-4 transition-all ease-in-out pb-2 text-lg active:border-b-ecsess-500 px-2"
|
||||
stateActive="border-b-ecsess-400"
|
||||
>
|
||||
{@render children()}
|
||||
</Tabs.Control>
|
||||
@@ -54,11 +54,11 @@
|
||||
|
||||
const isPastEvent = (dateString: string): boolean => {
|
||||
const eventDate = parseEventDate(dateString);
|
||||
// Add 1 day to the event date
|
||||
// Add 1 day to the event date
|
||||
const now = new Date();
|
||||
const eventDatePlusOneDay = new Date(eventDate.getTime() + 24 * 60 * 60 * 1000);
|
||||
|
||||
return now > eventDatePlusOneDay;
|
||||
const eventDatePlusOneDay = new Date(eventDate.getTime() + 24 * 60 * 60 * 1000);
|
||||
|
||||
return now > eventDatePlusOneDay;
|
||||
// return eventDate < now;
|
||||
};
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
);
|
||||
</script>
|
||||
|
||||
<Tabs.Panel {value}>
|
||||
<Tabs.Content {value}>
|
||||
<div class="space-y-12 px-4 py-8 lg:px-8">
|
||||
<!-- Upcoming Events -->
|
||||
{#if upcomingEvents.length > 0}
|
||||
@@ -139,4 +139,4 @@
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</Tabs.Panel>
|
||||
</Tabs.Content>
|
||||
15
src/components/event/EventTabsTrigger.svelte
Normal file
15
src/components/event/EventTabsTrigger.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<script>
|
||||
import { Tabs } from '@skeletonlabs/skeleton-svelte';
|
||||
let { value, children } = $props();
|
||||
</script>
|
||||
|
||||
<Tabs.Trigger {value}>
|
||||
{#snippet element(attributes)}
|
||||
<button
|
||||
{...attributes}
|
||||
class="hover:border-b-ecsess-200 data-[state=active]:border-b-ecsess-400 border-b-4 border-b-transparent px-2 pb-2 text-lg transition-all ease-in-out"
|
||||
>
|
||||
{@render children()}
|
||||
</button>
|
||||
{/snippet}
|
||||
</Tabs.Trigger>
|
||||
@@ -1,60 +1,54 @@
|
||||
<script lang="ts">
|
||||
import type { FAQ } from '$lib/schemas';
|
||||
import { Accordion } from '@skeletonlabs/skeleton-svelte';
|
||||
import { slide } from 'svelte/transition';
|
||||
|
||||
// Variable to be included into the component
|
||||
let { entries }: { entries: FAQ[] } = $props();
|
||||
</script>
|
||||
|
||||
<Accordion multiple>
|
||||
{#snippet iconClosed()}
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
><path d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
{/snippet}
|
||||
|
||||
{#snippet iconOpen()}
|
||||
<svg
|
||||
class="rotate-90"
|
||||
width="20"
|
||||
height="20"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
><path d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
{/snippet}
|
||||
|
||||
<Accordion multiple class="space-y-3">
|
||||
{#each entries as entry, index}
|
||||
<Accordion.Item
|
||||
value={index.toString()}
|
||||
classes="border-ecsess-300 mb-4 rounded-md border-2 hover:bg-ecsess-500/30 transition-all"
|
||||
leadClasses="text-lg font-bold"
|
||||
controlClasses="
|
||||
flex cursor-pointer justify-between
|
||||
py-4 ease-in-out"
|
||||
panelClasses=" border-t-ecsess-300 border-t-2 bg-transparent p-4 bg-ecsess-400/50"
|
||||
class="border-ecsess-300 hover:bg-ecsess-500/30 rounded-md border-2 transition-colors duration-200"
|
||||
>
|
||||
<!-- Control -->
|
||||
{#snippet lead()}
|
||||
<!-- Question -->
|
||||
<Accordion.ItemTrigger
|
||||
class="flex w-full items-center gap-3 px-3 py-2 text-left text-lg font-bold"
|
||||
>
|
||||
{entry.question}
|
||||
{/snippet}
|
||||
|
||||
{#snippet control()}{/snippet}
|
||||
<Accordion.ItemIndicator class="group ml-auto">
|
||||
<svg
|
||||
class="size-5 shrink-0 transition-transform duration-200 group-data-[state=open]:rotate-90"
|
||||
width="20"
|
||||
height="20"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
><path d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</Accordion.ItemIndicator>
|
||||
</Accordion.ItemTrigger>
|
||||
|
||||
<!-- Panel -->
|
||||
{#snippet panel()}{entry.answer}{/snippet}
|
||||
<Accordion.ItemContent class="border-t-ecsess-300 bg-ecsess-400/50 h-fit overflow-hidden">
|
||||
{#snippet element(attributes)}
|
||||
{#if !attributes.hidden}
|
||||
<div
|
||||
{...attributes}
|
||||
class="border-t-ecsess-300 overflow-hidden border-t-2 px-4 py-3
|
||||
text-base leading-relaxed transition-all duration-200"
|
||||
transition:slide={{ duration: 200 }}
|
||||
>
|
||||
{entry.answer}
|
||||
</div>
|
||||
{/if}
|
||||
{/snippet}
|
||||
</Accordion.ItemContent>
|
||||
</Accordion.Item>
|
||||
{/each}
|
||||
</Accordion>
|
||||
|
||||
@@ -42,14 +42,12 @@
|
||||
<div class="mb-6 grid grid-cols-1 gap-6 md:grid-cols-3">
|
||||
<!-- Left: ECSESS Lounge -->
|
||||
<div class="border-ecsess-800 border-b-1 pb-4 text-center md:border-0 md:text-left">
|
||||
<p class="text-ecsess-300 mb-3 text-lg">
|
||||
Visit the ECSESS lounge!
|
||||
</p>
|
||||
<p class="text-ecsess-300 mb-3 text-lg">Visit the ECSESS lounge!</p>
|
||||
<a
|
||||
href="https://maps.app.goo.gl/m9ZqjTrPM7pcBzhbA"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-ecsess-300 hover:text-ecsess-100 border-b-1 border-b-transparent hover:border-b-ecsess-100 inline-flex items-center gap-2 justify-baseline transition-all pb-0.5"
|
||||
class="text-ecsess-300 hover:text-ecsess-100 hover:border-b-ecsess-100 inline-flex items-center justify-baseline gap-2 border-b-1 border-b-transparent pb-0.5 transition-all"
|
||||
>
|
||||
<svg
|
||||
class="h-4 w-4 flex-shrink-0"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
const isActive = $derived(page.url.pathname === href);
|
||||
</script>
|
||||
|
||||
<a {href} class="w-auto mx-1">
|
||||
<a {href} class="mx-1 w-auto">
|
||||
<button
|
||||
class="hover:text-ecsess-100 hover:border-ecsess-100 text-ecsess-200 text-shadow-xl active:border-ecsess-500
|
||||
active:text-ecsess-500 mx-0.5 w-full rounded-none border-b-4 px-6 py-2
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
canonical = 'https://ecsess.mcgilleus.ca'
|
||||
} = $props();
|
||||
|
||||
let thumbnail = "https://cdn.sanity.io/images/vmtsvpe2/production/5d68504038cc692805dc5e51af83adedfefde442-5304x3443.jpg?h=628&fm=webp";
|
||||
let thumbnail =
|
||||
'https://cdn.sanity.io/images/vmtsvpe2/production/5d68504038cc692805dc5e51af83adedfefde442-5304x3443.jpg?h=628&fm=webp';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="bg-ecsess-100 text-ecsess-900 grid h-full place-content-center rounded-md text-center hover:bg-ecsess-200 border-ecsess-300 border shadow-md transition-all hover:shadow-lg"
|
||||
class="bg-ecsess-100 text-ecsess-900 hover:bg-ecsess-200 border-ecsess-300 grid h-full place-content-center rounded-md border text-center shadow-md transition-all hover:shadow-lg"
|
||||
>
|
||||
<p class="text-base font-extrabold lg:text-lg">
|
||||
{officeHour.member.name.split(' ')[0]}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
const DEFAULT_START_TIME = 10 * 60; // 10 AM in minutes
|
||||
const DEFAULT_END_TIME = 17 * 60; // 5 PM in minutes
|
||||
|
||||
type Segment = {
|
||||
type SegmentedControl = {
|
||||
startSlot: number;
|
||||
endSlot: number;
|
||||
ohs: OfficeHour[];
|
||||
@@ -86,8 +86,8 @@
|
||||
});
|
||||
|
||||
// Create continuous segments for a day
|
||||
const getSegmentsForDay = (day: string): Segment[] => {
|
||||
const segments: Segment[] = [];
|
||||
const getSegmentsForDay = (day: string): SegmentedControl[] => {
|
||||
const segments: SegmentedControl[] = [];
|
||||
|
||||
for (const currentSlot of timeSlots) {
|
||||
const activeOHs = getActiveOHs(day, currentSlot);
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
<script>
|
||||
import { CircleArrowRight } from '@lucide/svelte';
|
||||
import Link from 'components/Link.svelte';
|
||||
let { title = '_Resource Title_', description = "Lorem ipsum", link = 'https://example.com' } = $props();
|
||||
let {
|
||||
title = '_Resource Title_',
|
||||
description = 'Lorem ipsum',
|
||||
link = 'https://example.com'
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<div class="bg-ecsess-50 relative h-fit max-w-xl min-w-12 rounded-md px-4 py-2 md:py-0 hover:shadow-md transition-shadow border border-ecsess-100">
|
||||
<div
|
||||
class="bg-ecsess-50 border-ecsess-100 relative h-fit max-w-xl min-w-12 rounded-md border px-4 py-2 transition-shadow hover:shadow-md md:py-0"
|
||||
>
|
||||
<div class="grid grid-cols-1 md:grid-cols-[7fr_1fr]">
|
||||
<div class="flex flex-col items-start p-4">
|
||||
<p class="text-ecsess-900 my-1 pb-1 text-left text-xl font-extrabold">
|
||||
|
||||
Reference in New Issue
Block a user