Things seems like they are working
This commit is contained in:
35
src/app.css
35
src/app.css
@@ -2,18 +2,31 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
@theme {
|
||||
/* Light shades - for backgrounds and cards */
|
||||
--color-ecsess-50: #e8ffd9;
|
||||
--color-ecsess-100: #CCE7BA;
|
||||
--color-ecsess-200: #a9b7a0;
|
||||
--color-ecsess-300: #82a17f;
|
||||
--color-ecsess-400: #5c8a5c;
|
||||
--color-ecsess-500: #4b7b4b;
|
||||
--color-ecsess-600: #3b6a3a;
|
||||
--color-ecsess-700: #235323;
|
||||
--color-ecsess-150: #b8dda8;
|
||||
--color-ecsess-200: #a9d0a0;
|
||||
|
||||
/* Mid-light shades - for borders and hover states */
|
||||
--color-ecsess-300: #8fb98a;
|
||||
--color-ecsess-350: #7aa876;
|
||||
--color-ecsess-400: #6a9a6a;
|
||||
|
||||
/* Mid shades - for accents and interactive elements */
|
||||
--color-ecsess-500: #5a8b5a;
|
||||
--color-ecsess-550: #4d7a4d;
|
||||
--color-ecsess-600: #3f6a3f;
|
||||
|
||||
/* Mid-dark shades - for text on light backgrounds */
|
||||
--color-ecsess-700: #2d5a2d;
|
||||
--color-ecsess-800: #0a3d2a;
|
||||
|
||||
/* Dark shades - for text and backgrounds */
|
||||
--color-ecsess-900: #062c20;
|
||||
--color-ecsess-950: #031c15;
|
||||
--color-ecsess-teal: #168059;
|
||||
|
||||
/* Black variants for UI elements */
|
||||
--color-ecsess-black: #1F1F1F;
|
||||
--color-ecsess-black-hover: #161917;
|
||||
}
|
||||
@@ -53,7 +66,7 @@ h2 {
|
||||
}
|
||||
|
||||
blockquote {
|
||||
@apply bg-ecsess-200 text-ecsess-600 border-l-ecsess-800 my-4 rounded-sm border-l-4 py-[0.01rem] ps-4 italic;
|
||||
@apply bg-ecsess-100 text-ecsess-700 border-l-ecsess-600 my-4 rounded-md border-l-4 py-[0.01rem] ps-4 italic;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@@ -152,11 +165,11 @@ h2 {
|
||||
}
|
||||
|
||||
thead {
|
||||
@apply border-ecsess-400 border-b-2;
|
||||
@apply border-ecsess-500 border-b-2;
|
||||
}
|
||||
|
||||
thead th {
|
||||
@apply text-ecsess-400 p-2 text-left text-base font-bold;
|
||||
@apply text-ecsess-500 p-2 text-left text-base font-bold;
|
||||
}
|
||||
|
||||
tbody td,
|
||||
@@ -169,7 +182,7 @@ h2 {
|
||||
}
|
||||
|
||||
tbody tr:nth-child(odd) {
|
||||
@apply bg-ecsess-200/24;
|
||||
@apply bg-ecsess-150/24;
|
||||
}
|
||||
|
||||
td + td {
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
</script>
|
||||
|
||||
<button
|
||||
class="bg-ecsess-600 hover:bg-ecsess-400 active:bg-ecsess-800
|
||||
inline-block rounded-lg border-none px-4
|
||||
class="bg-ecsess-600 hover:bg-ecsess-500 active:bg-ecsess-700
|
||||
inline-block rounded-md border-none px-4
|
||||
py-2 text-white transition-all
|
||||
duration-200 ease-out
|
||||
hover:shadow-2xl"
|
||||
hover:shadow-xl hover:scale-105"
|
||||
{onclick}
|
||||
>
|
||||
{@render children()}
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
import Avatar from 'components/council/Avatar.svelte';
|
||||
</script>
|
||||
|
||||
<div class="text-ecsess-200 flex max-w-md items-center gap-6 p-3">
|
||||
<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 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-sm md:text-base text-ecsess-150 mb-2 italic">{position}</div>
|
||||
<Button onclick={onViewProfile}>View Profile</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
|
||||
<div
|
||||
class="text-ecsess-800 m-4 flex h-[275px] max-w-[564px]
|
||||
items-center gap-3 rounded-2xl border-transparent bg-transparent
|
||||
bg-[linear-gradient(to_bottom_right,_#E8FFD9,_#97C583)] p-6"
|
||||
items-center gap-3 rounded-md border-transparent bg-transparent
|
||||
bg-gradient-to-br from-ecsess-50 to-ecsess-300 p-6"
|
||||
transition:slide
|
||||
>
|
||||
<!-- AVATAR -->
|
||||
<div class="avatar">
|
||||
<div class="size-36 justify-center place-self-center-safe overflow-hidden rounded-lg shadow-md">
|
||||
<div class="size-36 justify-center place-self-center-safe overflow-hidden rounded-md shadow-md">
|
||||
<img src={image || placeholder} alt={name} class="h-full w-full object-cover" />
|
||||
</div>
|
||||
<span class="yearProgram justify-center text-sm"> Major: {yearProgram} </span>
|
||||
<span class="yearProgram justify-center text-sm"> {yearProgram} </span>
|
||||
</div>
|
||||
<!-- CONTENT -->
|
||||
<div class="content">
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<div class="mx-auto w-[100%] rounded-2xl bg-[#E8FFD9] p-5 text-[#0A3D2A] lg:w-[64%] lg:max-w-3xl">
|
||||
<div class="rounded-[20px] bg-[#A6D6B8]">
|
||||
<div class="mx-auto w-[100%] rounded-md bg-ecsess-50 p-5 text-ecsess-800 lg:w-[64%] lg:max-w-3xl">
|
||||
<div class="rounded-md bg-ecsess-150">
|
||||
<div
|
||||
class="grid h-[200px] place-items-center overflow-hidden rounded-[16px] bg-[#5CAF95]"
|
||||
class="grid h-[200px] place-items-center overflow-hidden rounded-md bg-ecsess-400"
|
||||
aria-label="Event banner"
|
||||
>
|
||||
{#if thumbnail}
|
||||
@@ -43,28 +43,28 @@
|
||||
</p>
|
||||
|
||||
{#if eventDescription}
|
||||
<div class="mx-auto max-w-[75ch] leading-relaxed text-[#5E8174]">
|
||||
<div class="mx-auto max-w-[75ch] leading-relaxed text-ecsess-700">
|
||||
<PortableText value={eventDescription} />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="mt-[6px] grid gap-4 md:grid-cols-2">
|
||||
<div class="grid gap-[10px] rounded-2xl bg-[#CCE7BA] px-4 py-[14px]">
|
||||
<div class="flex items-center gap-2 text-[#0A3D2A]">
|
||||
<div class="grid gap-[10px] rounded-md bg-ecsess-100 px-4 py-[14px]">
|
||||
<div class="flex items-center gap-2 text-ecsess-800">
|
||||
<CalendarDays class="shrink-0" strokeWidth={2.5} />
|
||||
<span class="font-bold tracking-[0.2px]">Datetime:</span>
|
||||
<p class="m-0 text-left">{date}</p>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 text-[#0A3D2A]">
|
||||
<div class="flex items-center gap-2 text-ecsess-800">
|
||||
<MapPin class="shrink-0" strokeWidth={2.5} />
|
||||
<span class="font-bold tracking-[0.2px]">Location:</span>
|
||||
<p class="m-0 text-left">{location ?? 'TBA'}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-[10px] rounded-2xl bg-[#CCE7BA] px-4 py-[14px]">
|
||||
<div class="flex items-center gap-2 text-[#0A3D2A]">
|
||||
<div class="grid gap-[10px] rounded-md bg-ecsess-100 px-4 py-[14px]">
|
||||
<div class="flex items-center gap-2 text-ecsess-800">
|
||||
<FilePen class="shrink-0" strokeWidth={2.5} />
|
||||
<span class="font-bold tracking-[0.2px]">Registration:</span>
|
||||
{#if registrationLink}
|
||||
@@ -72,7 +72,7 @@
|
||||
href={registrationLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-left text-[#0A3D2A] underline-offset-4 hover:underline"
|
||||
class="text-left text-ecsess-800 underline-offset-4 hover:underline"
|
||||
>
|
||||
Register Here
|
||||
</a>
|
||||
@@ -81,7 +81,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 text-[#0A3D2A]">
|
||||
<div class="flex items-center gap-2 text-ecsess-800">
|
||||
<LinkIcon class="shrink-0" strokeWidth={2.5} />
|
||||
<span class="font-bold tracking-[0.2px]">Payment:</span>
|
||||
{#if paymentLink}
|
||||
@@ -89,7 +89,7 @@
|
||||
href={paymentLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-left text-[#0A3D2A] underline-offset-4 hover:underline"
|
||||
class="text-left text-ecsess-800 underline-offset-4 hover:underline"
|
||||
>
|
||||
Pay Here
|
||||
</a>
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
<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-600 px-2"
|
||||
stateActive="border-b-ecsess-400"
|
||||
classes="hover:border-b-ecsess-150 border-b-4 transition-all ease-in-out pb-2 text-lg active:border-b-ecsess-500 px-2"
|
||||
stateActive="border-b-ecsess-350"
|
||||
>
|
||||
{@render children()}
|
||||
</Tabs.Control>
|
||||
|
||||
@@ -39,12 +39,12 @@
|
||||
{#each entries as entry, index}
|
||||
<Accordion.Item
|
||||
value={index.toString()}
|
||||
classes="border-ecsess-200 mb-4 rounded-xl border-2 hover:bg-ecsess-600/48 transition-all"
|
||||
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-200 border-t-2 bg-transparent p-4 bg-ecsess-400"
|
||||
panelClasses=" border-t-ecsess-300 border-t-2 bg-transparent p-4 bg-ecsess-350/50"
|
||||
>
|
||||
<!-- Control -->
|
||||
{#snippet lead()}
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
</script>
|
||||
|
||||
<footer
|
||||
class="bg-ecsess-black text-ecsess-200 mx-auto flex min-w-fit flex-wrap items-center justify-center px-4 py-4"
|
||||
class="bg-ecsess-black text-ecsess-100 mx-auto flex min-w-fit flex-wrap items-center justify-center px-4 py-4"
|
||||
>
|
||||
<div>
|
||||
<p class="text-ecsess-200 py-3 text-center">
|
||||
<p class="text-ecsess-150 py-3 text-center">
|
||||
Created by ECSESS with love {'<3'}. <br />
|
||||
© ECSESS {year}, under GNU General Public License v3.0.
|
||||
</p>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
let menuHidden = $state(true);
|
||||
</script>
|
||||
|
||||
<nav class="bg-ecsess-black text-ecsess-200 sticky w-full py-1">
|
||||
<nav class="bg-ecsess-black text-ecsess-100 sticky w-full py-1">
|
||||
<div class="block md:hidden">
|
||||
<div class="mx-4 flex items-center-safe justify-between">
|
||||
<a href="/">
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="bg-ecsess-black-hover hover:bg-ecsess-800 grid size-10 place-items-center rounded-lg transition-colors ease-in-out active:bg-green-900"
|
||||
class="bg-ecsess-black-hover hover:bg-ecsess-800 grid size-10 place-items-center rounded-md transition-colors ease-in-out active:bg-ecsess-900"
|
||||
onclick={() => {
|
||||
menuHidden = !menuHidden;
|
||||
}}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
<a {href}>
|
||||
<button
|
||||
class="border-ecsess-black hover:border-ecsess-200 active:border-ecsess-400 border-b-4 px-6 py-2
|
||||
font-semibold transition-all"
|
||||
class="border-ecsess-black hover:border-ecsess-150 active:border-ecsess-300 border-b-4 px-6 py-2
|
||||
font-semibold transition-all hover:text-ecsess-100"
|
||||
>
|
||||
{@render children()}
|
||||
</button>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
let { children = () => 'Section placeholder', black = false } = $props();
|
||||
|
||||
let tailwindClasses = $state(
|
||||
'mx-auto flex min-h-[90vh] flex-col items-center justify-center gap-4 p-4 text-center text-ecsess-200'
|
||||
'mx-auto flex min-h-[90vh] flex-col items-center justify-center gap-4 p-4 text-center text-ecsess-100'
|
||||
);
|
||||
|
||||
if (black) {
|
||||
|
||||
@@ -1,63 +1,23 @@
|
||||
<script lang="ts">
|
||||
import type { OfficeHour } from '$lib/schemas';
|
||||
|
||||
let { officeHour, compact = false, hideTime = false }: { officeHour: OfficeHour; compact?: boolean; hideTime?: boolean } = $props();
|
||||
let { officeHour, isShortBlock }: { officeHour: OfficeHour; isShortBlock: boolean } = $props();
|
||||
|
||||
function parseTime(timeStr: string): number {
|
||||
let timeRegexMatch = timeStr.match(/^(\d{1,2})(?::(\d{2}))?(AM|PM)$/i);
|
||||
if (!timeRegexMatch) return 0;
|
||||
|
||||
let hours = parseInt(timeRegexMatch[1], 10);
|
||||
let minutes = parseInt(timeRegexMatch[2] || '0', 10);
|
||||
let period = timeRegexMatch[3];
|
||||
|
||||
if (period.toUpperCase() === 'PM' && hours !== 12) hours += 12;
|
||||
if (period.toUpperCase() === 'AM' && hours === 12) hours = 0;
|
||||
|
||||
return hours * 60 + minutes;
|
||||
function shortenPosition(position: string): string {
|
||||
return position.replace(/Engineering Representative/gi, 'Rep.');
|
||||
}
|
||||
|
||||
// Calculate duration in minutes
|
||||
function getDuration(start: string, end: string): number {
|
||||
return parseTime(end) - parseTime(start);
|
||||
}
|
||||
|
||||
// Calculate dynamic height based on duration
|
||||
// Base: 30 minutes = 3.5rem, scale proportionally
|
||||
function getHeight(duration: number): string {
|
||||
const baseMinutes = 30;
|
||||
const baseHeight = 3.5; // Half of original 7rem
|
||||
const heightRem = Math.max((duration / baseMinutes) * baseHeight, 2.5);
|
||||
return `${heightRem}rem`;
|
||||
}
|
||||
|
||||
const duration = getDuration(officeHour.startTime, officeHour.endTime);
|
||||
const blockHeight = getHeight(duration);
|
||||
|
||||
// Shorten position name for display
|
||||
const displayPosition = officeHour.member.position.replace(/Engineering Representative/gi, 'Rep.');
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="bg-ecsess-200 text-ecsess-black grid place-content-center rounded-lg text-center h-full"
|
||||
class:m-2={!compact && !hideTime}
|
||||
class:m-0={hideTime}
|
||||
class:p-2={!hideTime}
|
||||
class:p-1={hideTime}
|
||||
style={hideTime ? '' : `height: ${blockHeight};`}
|
||||
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"
|
||||
>
|
||||
{#if !hideTime}
|
||||
<p class="border-b-ecsess-600 border-b-2 text-xs md:text-sm" class:lg:text-base={!compact} class:lg:text-sm={compact}>
|
||||
{officeHour.startTime} - {officeHour.endTime}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<p class="text-ecsess-800 font-extrabold text-base lg:text-lg">
|
||||
<p class="text-base font-extrabold lg:text-lg">
|
||||
{officeHour.member.name.split(' ')[0]}
|
||||
</p>
|
||||
|
||||
<p class="italic text-xs">
|
||||
{displayPosition}
|
||||
</p>
|
||||
{#if !isShortBlock}
|
||||
<p class="text-ecsess-700 text-xs italic">
|
||||
{shortenPosition(officeHour.member.position)}
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { OfficeHour } from '$lib/schemas';
|
||||
import OHBlock from './OHBlock.svelte';
|
||||
|
||||
// Constants
|
||||
const SLOT_HEIGHT = 40; // pixels per 30-minute slot
|
||||
@@ -8,7 +9,7 @@
|
||||
const BLOCK_VERTICAL_PADDING = 8; // pixels total (4px top + 4px bottom)
|
||||
const DAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] as const;
|
||||
const DEFAULT_START_TIME = 10 * 60; // 10 AM in minutes
|
||||
const DEFAULT_END_TIME = 17 * 60 ; // 5 PM in minutes
|
||||
const DEFAULT_END_TIME = 17 * 60; // 5 PM in minutes
|
||||
|
||||
type Segment = {
|
||||
startSlot: number;
|
||||
@@ -42,14 +43,17 @@
|
||||
};
|
||||
|
||||
const getSegmentId = (ohs: OfficeHour[]): string =>
|
||||
ohs.map(oh => `${oh.member.name}|${oh.startTime}`).sort().join('||');
|
||||
ohs
|
||||
.map((oh) => `${oh.member.name}|${oh.startTime}`)
|
||||
.sort()
|
||||
.join('||');
|
||||
|
||||
// Derived values using Svelte 5 $derived
|
||||
const timeRange = $derived.by(() => {
|
||||
const allTimes = allOhs.flatMap(oh => [parseTime(oh.startTime), parseTime(oh.endTime)]);
|
||||
const allTimes = allOhs.flatMap((oh) => [parseTime(oh.startTime), parseTime(oh.endTime)]);
|
||||
return {
|
||||
min: Math.min(...allTimes, DEFAULT_START_TIME),
|
||||
max: Math.max(...allTimes, DEFAULT_END_TIME),
|
||||
max: Math.max(...allTimes, DEFAULT_END_TIME)
|
||||
};
|
||||
});
|
||||
|
||||
@@ -74,7 +78,7 @@
|
||||
|
||||
// Get office hours active at a specific time slot
|
||||
const getActiveOHs = (day: string, timeSlot: number): OfficeHour[] =>
|
||||
allOhs.filter(oh => {
|
||||
allOhs.filter((oh) => {
|
||||
if (oh.day !== day) return false;
|
||||
const start = parseTime(oh.startTime);
|
||||
const end = parseTime(oh.endTime);
|
||||
@@ -100,44 +104,44 @@
|
||||
segments.push({
|
||||
startSlot: currentSlot,
|
||||
endSlot: currentSlot + SLOT_DURATION,
|
||||
ohs: activeOHs,
|
||||
ohs: activeOHs
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return segments;
|
||||
};
|
||||
|
||||
const shortenPosition = (position: string): string =>
|
||||
position.replace(/Engineering Representative/gi, 'Rep.');
|
||||
</script>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<div class="min-w-[800px] max-w-7xl mx-auto">
|
||||
<div class="mx-auto max-w-7xl min-w-[800px]">
|
||||
<!-- Header row -->
|
||||
<div class="grid gap-0 mb-2" style:grid-template-columns="80px repeat(5, 1fr)">
|
||||
<div class="text-center font-semibold text-ecsess-200 text-base px-2">Time</div>
|
||||
<div class="mb-2 grid gap-0" style:grid-template-columns="80px repeat(5, 1fr)">
|
||||
<div class="text-ecsess-50 px-2 text-center text-base font-semibold">Time</div>
|
||||
{#each DAYS as day}
|
||||
<div class="text-center font-semibold text-ecsess-200 text-base md:text-lg px-2">
|
||||
<div class="text-ecsess-50 px-2 text-center text-base font-semibold md:text-lg">
|
||||
{day}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<!-- Calendar grid -->
|
||||
<div class="grid gap-0 border-t-2 border-ecsess-600" style:grid-template-columns="80px repeat(5, 1fr)">
|
||||
<div
|
||||
class="border-ecsess-500 grid gap-0 border-t-2"
|
||||
style:grid-template-columns="80px repeat(5, 1fr)"
|
||||
>
|
||||
{#each DAYS as day, dayIndex}
|
||||
{@const segments = getSegmentsForDay(day)}
|
||||
|
||||
<!-- Time column (only for first day) -->
|
||||
{#if dayIndex === 0}
|
||||
<div class="relative border-b-2 border-ecsess-600">
|
||||
<div class="border-ecsess-500 relative border-b-2">
|
||||
{#each timeSlots as timeSlot}
|
||||
{@const isHourMark = timeSlot % 60 === 0}
|
||||
<div
|
||||
class="flex items-start pt-1 text-right pr-2 text-sm text-ecsess-200 border-t border-ecsess-700"
|
||||
class="text-ecsess-50 border-ecsess-400 flex items-start justify-end border-t pt-1 pr-2 text-sm"
|
||||
class:border-t-4={isHourMark}
|
||||
class:border-ecsess-600={isHourMark}
|
||||
class:border-ecsess-500={isHourMark}
|
||||
class:font-semibold={isHourMark}
|
||||
style:height="{SLOT_HEIGHT}px"
|
||||
>
|
||||
@@ -148,14 +152,17 @@
|
||||
{/if}
|
||||
|
||||
<!-- Day column with segments -->
|
||||
<div class="relative border-l border-b-2 border-ecsess-700 border-b-ecsess-600" style:min-height="{timeSlots.length * SLOT_HEIGHT}px">
|
||||
<div
|
||||
class="border-ecsess-500 border-b-ecsess-500 relative border-b-2 border-l"
|
||||
style:min-height="{timeSlots.length * SLOT_HEIGHT}px"
|
||||
>
|
||||
<!-- Background grid lines -->
|
||||
{#each timeSlots as timeSlot, idx}
|
||||
{@const isHourMark = timeSlot % 60 === 0}
|
||||
<div
|
||||
class="absolute inset-x-0 border-t border-ecsess-700"
|
||||
class="border-ecsess-400 absolute inset-x-0 border-t"
|
||||
class:border-t-4={isHourMark}
|
||||
class:border-ecsess-600={isHourMark}
|
||||
class:border-ecsess-500={isHourMark}
|
||||
style:top="{idx * SLOT_HEIGHT}px"
|
||||
style:height="{SLOT_HEIGHT}px"
|
||||
></div>
|
||||
@@ -163,32 +170,21 @@
|
||||
|
||||
<!-- Office hour segments -->
|
||||
{#each segments as segment}
|
||||
{@const startIndex = timeSlots.findIndex(ts => ts >= segment.startSlot)}
|
||||
{@const startIndex = timeSlots.findIndex((ts) => ts >= segment.startSlot)}
|
||||
{@const duration = segment.endSlot - segment.startSlot}
|
||||
{@const heightPx = (duration / SLOT_DURATION) * SLOT_HEIGHT}
|
||||
{@const isShortBlock = duration <= SLOT_DURATION}
|
||||
{@const isShortBlock = duration <= 30}
|
||||
|
||||
<div
|
||||
class="absolute grid gap-0.5 z-10"
|
||||
style:top="{startIndex * SLOT_HEIGHT + BLOCK_MARGIN}px"
|
||||
style:height="{heightPx - BLOCK_VERTICAL_PADDING}px"
|
||||
class="absolute z-10 grid gap-0.5"
|
||||
style:top="{startIndex * SLOT_HEIGHT + BLOCK_MARGIN + 3}px"
|
||||
style:height="{heightPx - BLOCK_VERTICAL_PADDING - 3}px"
|
||||
style:left="{BLOCK_MARGIN}px"
|
||||
style:right="{BLOCK_MARGIN}px"
|
||||
style:grid-template-columns="repeat({segment.ohs.length}, 1fr)"
|
||||
>
|
||||
{#each segment.ohs as oh}
|
||||
<div class="min-w-0 bg-ecsess-200 rounded-sm flex items-center justify-center">
|
||||
<div class="text-center px-1">
|
||||
<p class="text-ecsess-800 font-extrabold text-base lg:text-lg">
|
||||
{oh.member.name.split(' ')[0]}
|
||||
</p>
|
||||
{#if !isShortBlock}
|
||||
<p class="italic text-sm leading-tight text-ecsess-900">
|
||||
{shortenPosition(oh.member.position)}
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<OHBlock officeHour={oh} {isShortBlock} />
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
@@ -196,4 +192,4 @@
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
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-lg px-4 py-2 md:py-0">
|
||||
<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-150">
|
||||
<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">
|
||||
{title}
|
||||
</p>
|
||||
<p class="text-ecsess-600 text-left text-base">
|
||||
<p class="text-ecsess-700 text-left text-base">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
@@ -18,7 +18,7 @@
|
||||
<Link href={link}>
|
||||
<CircleArrowRight
|
||||
size="42"
|
||||
class="stroke-ecsess-800 hover:stroke-ecsess-400 cursor-pointer transition duration-200 active:scale-90"
|
||||
class="stroke-ecsess-700 hover:stroke-ecsess-500 cursor-pointer transition duration-200 active:scale-90"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
<p class="italic">
|
||||
Development progress: {progress}%
|
||||
</p>
|
||||
<div id="progress" class="my-2 border-2">
|
||||
<Progress value={progress} max={100} meterBg="bg-ecsess-200" height="h-4"></Progress>
|
||||
<div id="progress" class="my-2 border-2 border-ecsess-300">
|
||||
<Progress value={progress} max={100} meterBg="bg-ecsess-150" height="h-4"></Progress>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -48,7 +48,7 @@
|
||||
<img
|
||||
src={data.councilPhoto}
|
||||
alt="ECSESS Council"
|
||||
class="ring-ecsess-600 shadow-ecsess-400 rounded-2xl shadow-md ring-4"
|
||||
class="ring-ecsess-500 shadow-ecsess-350 rounded-md shadow-md ring-4 hover:ring-ecsess-400 transition-all"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -52,12 +52,12 @@
|
||||
<img
|
||||
src={data.councilGoofyPic.url}
|
||||
alt="ECSESS Council, but we are goofy"
|
||||
class="ring-ecsess-400 shadow-ecsess-black mb-8 rounded-lg shadow-2xl ring-4 lg:w-[90%]"
|
||||
class="ring-ecsess-350 shadow-ecsess-black mb-8 rounded-md shadow-2xl ring-4 lg:w-[90%] hover:ring-ecsess-300 transition-all"
|
||||
transition:fly
|
||||
/>
|
||||
</div>
|
||||
|
||||
<h1 class="border-b-ecsess-200 w-full border-b-2 lg:w-1/2">Our Student Council!</h1>
|
||||
<h1 class="border-b-ecsess-300 w-full border-b-2 lg:w-1/2">Our Student Council!</h1>
|
||||
|
||||
<div>
|
||||
<CardCouncil
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
<div class="grid place-items-center">
|
||||
<h2
|
||||
class="border-b-ecsess-200 w-full place-self-center-safe border-b-2 border-dashed md:w-1/2 lg:w-1/3"
|
||||
class="border-b-ecsess-300 w-full place-self-center-safe border-b-2 border-dashed md:w-1/2 lg:w-1/3"
|
||||
>
|
||||
Vice Presidents
|
||||
</h2>
|
||||
@@ -85,7 +85,7 @@
|
||||
{/each}
|
||||
</div>
|
||||
<h2
|
||||
class="border-b-ecsess-200 w-full place-self-center-safe border-b-2 border-dashed md:w-1/2 lg:w-1/3"
|
||||
class="border-b-ecsess-300 w-full place-self-center-safe border-b-2 border-dashed md:w-1/2 lg:w-1/3"
|
||||
>
|
||||
Year Representative
|
||||
</h2>
|
||||
|
||||
Reference in New Issue
Block a user