Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ export const metadata: Metadata = {
siteName: "3D Western",
images: [
{
url: "https://3dwestern.ca/banner.png",
url: "https://3dwestern.ca/preview.png",
width: 1200,
height: 630,
alt: "3D Western: Western University's Official 3D Printing Club",
alt: "3D Western: Build Create Maker Space",
},
],
locale: "en_US",
Expand All @@ -47,7 +47,7 @@ export const metadata: Metadata = {
description: "Western University's Official 3D Printing Club",
images: [
{
url: "https://3dwestern.ca/banner.png",
url: "https://3dwestern.ca/preview.png",
width: 1200,
height: 630,
alt: "3D Western: Western University's Official 3D Printing Club",
Expand Down
4 changes: 2 additions & 2 deletions src/components/EventCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export function EventCard({ event, onCardClick }: EventCardProps) {
/>
<div className="absolute inset-0 bg-black opacity-50 z-10" />
<div className="relative p-6 flex flex-col justify-end h-full text-white z-20">
<h3 className="text-2xl font-bold">{event.title}</h3>
<p className="text-sm">{event.date}</p>
<h3 className="text-2xl font-bold drop-shadow-lg">{event.title}</h3>
<p className="text-sm drop-shadow-md">{event.date}</p>
</div>
</Card>
);
Expand Down
26 changes: 13 additions & 13 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,42 +15,42 @@ export function Footer() {
<span className="tracking-tight font-bold">3D Western</span>
</div>
</div>
<p className="text-slate-400 max-w-md">
<p className="text-slate-200 max-w-md">
Empowering Students to Build &amp; Create.
</p>
<a href="/documents/3DW_ToS.pdf" className="underline text-slate-400 max-w-md">Terms of Service</a>
<a href="/documents/3DW_ToS.pdf" className="underline text-slate-200 max-w-md">Terms of Service</a>
</div>

{/* Quick Links */}
<div>
<ul className="space-y-2">
<li>
<Link href="/" className="text-slate-400 hover:text-white transition-colors hover:scale-110 hover:font-bold">
<Link href="/" className="text-slate-200 hover:text-white hover:translate-x-1 transition-all">
Home
</Link>
</li>
<li>
<Link href="/contact" className="text-slate-400 hover:text-white transition-colors hover:scale-110 hover:font-bold">
<Link href="/contact" className="text-slate-200 hover:text-white hover:translate-x-1 transition-all">
Contact Us
</Link>
</li>
<li>
<Link href="/makerspace" className="text-slate-400 hover:text-white transition-colors hover:scale-110 hover:font-bold">
<Link href="/makerspace" className="text-slate-200 hover:text-white hover:translate-x-1 transition-all">
Availability
</Link>
</li>
<li>
<Link href="https://westernu.brightspace.com/d2l/le/discovery/view/course/151344" className="text-slate-400 hover:text-white transition-colors hover:scale-110 hover:font-bold">
<Link href="https://westernu.brightspace.com/d2l/le/discovery/view/course/151344" className="text-slate-200 hover:text-white hover:translate-x-1 transition-all">
Training
</Link>
</li>
<li>
<Link href="/events" className="text-slate-400 hover:text-white transition-colors hover:scale-110 hover:font-bold">
<Link href="/events" className="text-slate-200 hover:text-white hover:translate-x-1 transition-all">
Events
</Link>
</li>
{/*<li>
<Link href="/dashboard" className="text-slate-400 hover:text-white transition-colors hover:scale-110 hover:font-bold">
<Link href="/dashboard" className="text-slate-200 hover:text-white hover:translate-x-1 transition-all">
Dashboard
</Link>
</li>*/}
Expand All @@ -60,11 +60,11 @@ export function Footer() {
{/* right columns */}
<div className="lg:border-l lg:border-purple-800 lg:pl-8 flex flex-col sm:flex-row items-center gap-8">
<ul className="space-y-3">
<li className="flex items-start gap-2 text-slate-400">
<li className="flex items-start gap-2 text-slate-200">
<Mail size={20} className="mt-0.5 flex-shrink-0" />
<a href="mailto:contact@3dwestern.ca" className="hover:text-white transition-colors">contact@3dwestern.ca</a>
</li>
<li className="flex items-start gap-2 text-slate-400">
<li className="flex items-start gap-2 text-slate-200">
<MapPin size={20} className="mt-0.5 flex-shrink-0" />
<span>Ronald D. Schmeichel Building for Entrepreneurship and Innovation, Western University</span>
</li>
Expand All @@ -76,7 +76,7 @@ export function Footer() {
href="https://www.instagram.com/3dwestern/"
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-2 text-slate-400 hover:text-white transition-colors hover:scale-110 hover:font-bold"
className="flex items-center justify-center p-2 text-slate-200 hover:text-white transition-colors"
aria-label="Instagram"
>
<Image
Expand All @@ -93,7 +93,7 @@ export function Footer() {
href="https://www.linkedin.com/company/3d-western/"
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-2 text-slate-400 hover:text-white transition-colors hover:scale-110 hover:font-bold"
className="flex items-center justify-center p-2 text-slate-200 hover:text-white transition-colors"
aria-label="LinkedIn"
>
<Image
Expand All @@ -109,7 +109,7 @@ export function Footer() {
</div>
</div>

<div className="border-t border-purple-800 mt-12 pt-8 text-center text-slate-400">
<div className="border-t border-purple-800 mt-12 pt-8 text-center text-slate-200">
<p>
Made by{' '}
<a
Expand Down
38 changes: 30 additions & 8 deletions src/components/pages/ContactPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
import { koulen } from '@/lib/fonts';
import Link from 'next/link';
import { motion } from 'framer-motion';
import { Loader2 } from 'lucide-react';


export function ContactPage() {
Expand Down Expand Up @@ -92,22 +93,30 @@ export function ContactPage() {

<div className="grid md:grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="firstName">First Name</Label>
<Label htmlFor="firstName">
First Name <span className="text-red-500" aria-label="required">*</span>
</Label>
<Input id="firstName" name="firstName" placeholder="John" required />
</div>
<div className="space-y-2">
<Label htmlFor="lastName">Last Name</Label>
<Label htmlFor="lastName">
Last Name <span className="text-red-500" aria-label="required">*</span>
</Label>
<Input id="lastName" name="lastName" placeholder="Doe" required />
</div>
</div>

<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Label htmlFor="email">
Email <span className="text-red-500" aria-label="required">*</span>
</Label>
<Input id="email" name="email" type="email" placeholder="john.doe@uwo.ca" required />
</div>

<div className="space-y-2">
<Label htmlFor="inquiryType">Inquiry Type</Label>
<Label htmlFor="inquiryType">
Inquiry Type <span className="text-red-500" aria-label="required">*</span>
</Label>
<Select value={inquiryType} onValueChange={setInquiryType}>
<SelectTrigger
id="inquiryType"
Expand All @@ -125,12 +134,16 @@ export function ContactPage() {
</div>

<div className="space-y-2">
<Label htmlFor="subject">Subject</Label>
<Label htmlFor="subject">
Subject <span className="text-red-500" aria-label="required">*</span>
</Label>
<Input id="subject" name="subject" placeholder="Brief description of your inquiry" required />
</div>

<div className="space-y-2">
<Label htmlFor="message">Message</Label>
<Label htmlFor="message">
Message <span className="text-red-500" aria-label="required">*</span>
</Label>
<Textarea
id="message"
name="message"
Expand All @@ -147,12 +160,21 @@ export function ContactPage() {
size="lg"
disabled={isSubmitting}
>
{isSubmitting ? 'Sending...' : 'Send Message'}
{isSubmitting ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Sending...
</>
) : (
'Send Message'
)}
</Button>
</div>

{result && (
<p className="text-sm text-muted-foreground text-center">{result}</p>
<div role="status" aria-live="polite" className="text-sm text-muted-foreground text-center">
{result}
</div>
)}
</form>
</CardContent>
Expand Down
9 changes: 6 additions & 3 deletions src/components/sections/FAQSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,14 @@ export function FAQSection() {
viewport={{ once: true, margin: "-30px" }}
transition={{ duration: 0.4, delay: index * 0.05 }}
>
<AccordionItem value={`item-${faq.id}`}>
<AccordionTrigger className="text-md sm:text-lg md:text-xl text-left">
<AccordionItem
value={`item-${faq.id}`}
className="border-l-2 border-transparent hover:border-slate-300 transition-colors data-[state=open]:bg-slate-50 data-[state=open]:border-purple-500"
>
<AccordionTrigger className="text-md sm:text-lg md:text-xl text-left transition-colors hover:text-slate-700 data-[state=open]:text-purple-700 data-[state=open]:font-semibold">
{faq.question}
</AccordionTrigger>
<AccordionContent className="text-sm md:text-md lg:text-lg text-muted-foreground">
<AccordionContent className="text-sm md:text-md lg:text-lg text-muted-foreground pl-4">
{faq.answer}
</AccordionContent>
</AccordionItem>
Expand Down
39 changes: 38 additions & 1 deletion src/components/sections/MorissetteModel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useLoading } from "@/context/LoadingContext";
import { useState, useEffect } from "react";
import { X } from "lucide-react";
import { X, ChevronDown } from "lucide-react";
import dynamic from "next/dynamic";
import { HorizontalNav } from "@/components/HorizontalNav";
import { motion, AnimatePresence } from "framer-motion";
Expand Down Expand Up @@ -44,6 +44,7 @@ const ANIMATION_DELAYS = {
TOAST_APPEAR: 500,
TOAST_DISMISS: 500,
SCROLL_THRESHOLD: 50,
SCROLL_INDICATOR_DELAY: 3000, // 3 seconds
} as const;

export function MorissetteModel() {
Expand All @@ -52,6 +53,7 @@ export function MorissetteModel() {
const [disclaimerVisible, setDisclaimerVisible] = useState(true);
const [disclaimerAnimating, setDisclaimerAnimating] = useState(false);
const [isScrolled, setIsScrolled] = useState(false);
const [scrollIndicatorVisible, setScrollIndicatorVisible] = useState(false);

// Trigger toast animation after loading completes
useEffect(() => {
Expand All @@ -77,6 +79,16 @@ export function MorissetteModel() {
return () => window.removeEventListener("scroll", handleScroll);
}, []);

// Show scroll indicator after 3 seconds of page load
useEffect(() => {
if (loadingComplete && !isScrolled) {
const timer = setTimeout(() => {
setScrollIndicatorVisible(true);
}, ANIMATION_DELAYS.SCROLL_INDICATOR_DELAY);
return () => clearTimeout(timer);
}
}, [loadingComplete, isScrolled]);

const handleDismiss = () => {
setDisclaimerAnimating(false);
setTimeout(() => setDisclaimerVisible(false), ANIMATION_DELAYS.TOAST_DISMISS);
Expand Down Expand Up @@ -130,6 +142,31 @@ export function MorissetteModel() {
<div className="absolute inset-0 z-1" style={{ pointerEvents: 'none' }}>
{loadingComplete && <AssemblyViewer />}
</div>

{/* Scroll Indicator */}
<AnimatePresence>
{scrollIndicatorVisible && !isScrolled && !isMenuOpen && (
<motion.div
className="absolute bottom-8 left-1/2 -translate-x-1/2 z-10 flex flex-col items-center"
initial={{ opacity: 0, y: -10 }}
animate={{
opacity: 1,
y: [0, 10, 0],
transition: {
opacity: { duration: 0.5, ease: "easeOut" },
y: {
duration: 1.5,
repeat: Infinity,
ease: "easeInOut",
},
},
}}
exit={{ opacity: 0, y: -10, transition: { duration: 0.3 } }}
>
<ChevronDown className="w-8 h-8 text-white opacity-60" />
</motion.div>
)}
</AnimatePresence>
</div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/ui/accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ function AccordionTrigger({
<AccordionPrimitive.Trigger
data-slot="accordion-trigger"
className={cn(
"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-5 sm:py-4 px-3 sm:px-2 text-left text-sm font-medium min-h-[60px] transition-all outline-none hover:bg-slate-100 hover:pl-4 sm:hover:pl-3 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180 cursor-pointer",
className,
)}
{...props}
>
{children}
<ChevronDownIcon className="text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" />
<ChevronDownIcon className="text-foreground pointer-events-none size-5 shrink-0 translate-y-0.5 transition-transform duration-200 opacity-60" />
</AccordionPrimitive.Trigger>
</AccordionPrimitive.Header>
);
Expand Down
Loading