Skip to content
Draft
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
218 changes: 218 additions & 0 deletions UI_UX_REVIEW_REPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
# 3D Western Website - UI/UX Review Report

**Date:** January 11, 2026
**Branch Reviewed:** main
**Reviewer:** Automated Browser Analysis

---

## Executive Summary

This report documents UI/UX findings and recommendations for the 3D Western website. The analysis covered the homepage, contact page, events page, makerspace/availability page, and mobile responsiveness.

---

## Pages Reviewed

### 1. Homepage

**Strengths:**
- Impressive 3D model hero section with smooth animations
- Clear value proposition with statistics (60+ Projects, 20+ Events, 50+ Active Visits)
- Well-organized content sections (About Us, Events, Makerspaces, Team, FAQs)
- Informative training banner with dismissible functionality
- Good use of visual hierarchy

**Issues Identified:**
- Hero section has no visible CTA button above the fold
- The 3D model, while impressive, may cause performance issues on lower-end devices

---

### 2. Contact Page

**Strengths:**
- Clean, accessible form layout
- Clear labels and placeholder text
- Inquiry type dropdown for categorization
- Response time expectation set ("1-2 business days")
- Link to FAQs as alternative resource

**Recommendations:**
- Consider adding form validation feedback before submission
- Add a phone number or alternative contact method for urgent inquiries

---

### 3. Events Page

**Strengths:**
- Clean grid layout for event cards
- Filtering tabs (All Events, Competitions, Workshops)
- Consistent card design with images, titles, and dates
- Clear CTA to contact for event organization

**Recommendations:**
- Add event descriptions visible on hover or click
- Consider adding a calendar view option
- Add registration/RSVP functionality

---

### 4. Makerspace/Availability Page

**Strengths:**
- Clear access requirements listed upfront
- Tab navigation between Digital and Sabourin makerspaces
- Typical hours displayed alongside calendar

**Issues Identified:**
- Google Calendar embed requires sign-in (401 error), making it inaccessible to unauthenticated users
- Calendar area appears blank/empty for visitors not logged into Google

**Recommendations:**
- Configure Google Calendar to be publicly viewable without sign-in
- Add a fallback display when calendar fails to load
- Consider embedding a public iCal feed instead

---

### 5. Mobile Responsiveness

**Strengths:**
- Hamburger menu works correctly
- Navigation menu is clean and readable when expanded
- 3D hero adapts well to smaller viewport
- Training banner displays appropriately on mobile
- Content reflows properly

**Recommendations:**
- Ensure all touch targets meet minimum 44x44px accessibility guidelines
- Test on actual mobile devices for performance verification

---

## Technical Issues (Console Warnings)

### Image Optimization Issues

The following images are missing the `sizes` prop when using `fill`:

| Image Path | Impact |
|------------|--------|
| `/logo.png` | Performance |
| `/images/lucky-block.webp` | Performance |
| `/images/workshop1.webp` | Performance |
| `/images/workshop2.webp` | Performance |
| `/images/workshop3.webp` | **LCP - High Priority** |
| `/images/workshop4.webp` | Performance |
| `/images/sewing.jpg` | Performance |

**Fix:** Add `sizes` prop to all Next.js Image components using `fill`:
```tsx
<Image
src="/images/workshop3.webp"
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
alt="Workshop"
/>
```

### Other Warnings

1. **Instagram SVG sizing:** Image has width or height modified but not both
- **File:** `/images/Instagram.svg`
- **Fix:** Ensure both width and height are set consistently

2. **Container positioning:** "Please ensure that the container has a non-static position"
- **Impact:** Affects 3D model rendering container
- **Fix:** Add `position: relative` to the parent container

---

## Performance Recommendations

### High Priority

1. **Add `sizes` prop to LCP image** (`workshop3.webp`)
- This image was detected as the Largest Contentful Paint element
- Missing `sizes` causes unnecessary bandwidth usage

2. **Fix Google Calendar authentication**
- Current setup requires user sign-in
- Make calendar publicly viewable or use a public embed URL

### Medium Priority

3. **Optimize 3D model loading**
- Consider adding a loading skeleton/placeholder
- Implement progressive loading for the GLTF model

4. **Add image `sizes` to all fill images**
- Reduces bandwidth on mobile devices
- Improves Core Web Vitals scores

### Low Priority

5. **Fix Instagram SVG dimensions**
- Set both width and height explicitly

6. **Add relative positioning to containers**
- Prevents layout warnings

---

## Accessibility Recommendations

1. **Focus indicators:** Ensure all interactive elements have visible focus states
2. **Color contrast:** Verify text contrast ratios meet WCAG AA standards
3. **Alt text:** Review all images for descriptive alt text
4. **Keyboard navigation:** Test full keyboard navigation flow
5. **Screen reader testing:** Verify semantic HTML structure

---

## Feature Recommendations

### Short-term
- Add a prominent CTA button in the hero section
- Implement form validation with user feedback
- Fix calendar embed accessibility

### Medium-term
- Add event registration functionality
- Implement equipment booking system preview
- Add project gallery/showcase section

### Long-term
- User dashboard for tracking projects
- Equipment availability real-time status
- Community forum or discussion board

---

## Files to Modify

| File | Changes Needed |
|------|----------------|
| `src/components/sections/EventsSection.tsx` | Add `sizes` to event card images |
| `src/components/sections/PhoneHeroSection.tsx` | Add container positioning fix |
| `src/components/Navigation.tsx` | Fix Instagram SVG dimensions |
| `src/components/sections/CalendarSection.tsx` | Fix Google Calendar public access |
| Various image components | Add `sizes` prop to fill images |

---

## Conclusion

The 3D Western website has a strong foundation with impressive visual design and good mobile responsiveness. The primary areas for improvement are:

1. **Image optimization** - Adding `sizes` props for better performance
2. **Calendar accessibility** - Making the Google Calendar publicly viewable
3. **User engagement** - Adding more CTAs and interactive features

Implementing these changes will improve performance, accessibility, and user experience.

---

*Report generated via automated browser analysis*
1 change: 1 addition & 0 deletions src/components/EventCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export function EventCard({ event, onCardClick }: EventCardProps) {
src={event.image}
alt={event.alt}
fill
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
className="object-cover transition-transform duration-300 ease-in-out group-hover:scale-105"
/>
<div className="absolute inset-0 bg-black opacity-50 z-10" />
Expand Down
2 changes: 2 additions & 0 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export function Footer() {
width={30}
height={30}
className="flex-shrink-0"
style={{ width: 30, height: 30 }}
/>
</a>
</li>
Expand All @@ -102,6 +103,7 @@ export function Footer() {
width={30}
height={30}
className="flex-shrink-0"
style={{ width: 30, height: 30 }}
/>
</a>
</li>
Expand Down
3 changes: 2 additions & 1 deletion src/components/HomeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ export function HomeButton() {
<Link
href="/"
className="fixed top-4 left-4 z-50 bg-white border border-gray-200 shadow-md rounded-full p-2 hover:bg-purple-50 transition-colors flex items-center justify-center transition-transform duration-200 transform hover:scale-110"
style={{ textDecoration: 'none', width: 48, height: 48 }}
style={{ textDecoration: 'none', width: 48, height: 48, position: 'relative' }}
aria-label="Home"
>
<Image
src="/logo.png"
alt="Home"
fill
sizes="48px"
style={{ objectFit: 'cover' }}
priority
/>
Expand Down
4 changes: 3 additions & 1 deletion src/components/LandingButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export function LandingButton({ isMobile }: { isMobile: boolean }) {
src="/logo.png"
alt="Home"
fill
sizes="48px"
style={{ objectFit: 'cover' }}
priority
/>
Expand All @@ -34,13 +35,14 @@ export function LandingButton({ isMobile }: { isMobile: boolean }) {
<Link
href="/"
className="hidden sm:block fixed top-10 left-12 z-50 bg-white border border-gray-200 shadow-md rounded-full p-2 hover:bg-purple-50 transition-colors flex items-center justify-center transition-transform duration-200 transform hover:scale-110"
style={{ textDecoration: 'none', width: 48, height: 48 }}
style={{ textDecoration: 'none', width: 48, height: 48, position: 'relative' }}
aria-label="Home"
>
<Image
src="/logo.png"
alt="Home"
fill
sizes="48px"
style={{ objectFit: 'cover' }}
priority
/>
Expand Down
89 changes: 67 additions & 22 deletions src/components/sections/CalendarSection.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,62 @@
import { Calendar } from 'lucide-react';
'use client';

import { useState } from 'react';
import { Calendar, AlertCircle, ExternalLink } from 'lucide-react';
import { Card, CardContent } from '@/components/ui/card';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';

function CalendarEmbed({
src,
title,
calendarUrl
}: {
src: string;
title: string;
calendarUrl: string;
}) {
const [showCalendar, setShowCalendar] = useState(false);

return (
<div className="h-[400px] sm:h-[500px] w-full bg-slate-100 rounded-lg flex items-center justify-center sm:border-2 sm:border-dashed relative overflow-hidden">
{!showCalendar ? (
<div className="flex flex-col items-center justify-center text-center p-6">
<AlertCircle className="w-12 h-12 text-amber-500 mb-4" />
<h4 className="text-lg font-semibold mb-2">Calendar May Require Sign-in</h4>
<p className="text-muted-foreground max-w-md mb-4">
The embedded calendar may require a Google account to view. Check the typical hours below or try loading the calendar.
</p>
<div className="flex flex-col sm:flex-row gap-3">
<button
onClick={() => setShowCalendar(true)}
className="px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors"
>
Try Loading Calendar
</button>
<a
href={calendarUrl}
target="_blank"
rel="noopener noreferrer"
className="px-4 py-2 border border-purple-600 text-purple-600 rounded-lg hover:bg-purple-50 transition-colors inline-flex items-center gap-2"
>
Open in Google Calendar
<ExternalLink size={16} />
</a>
</div>
</div>
) : (
<iframe
src={src}
style={{ borderWidth: 'solid 1px #777', width: '100%', height: '100%' }}
width="1000"
height="600"
title={title}
allowFullScreen
/>
)}
</div>
);
}

export function CalendarSection() {
return (
<section className="py-20 bg-slate-50">
Expand Down Expand Up @@ -29,16 +84,11 @@ export function CalendarSection() {


{/* digital makerspace calendar */}
<div className="h-[400px] sm:h-screen w-full bg-slate-100 rounded-lg flex items-center justify-center sm:border-2 sm:border-dashed">
<iframe
src="https://calendar.google.com/calendar/embed?src=195d4999e6906278ce183970e2cf265b0a470d9a35e20e80ac2bd15d5f6f783a%40group.calendar.google.com&ctz=America%2FToronto&mode=WEEK"
style={{ borderWidth: 'solid 1px #777', width: '100%', height: '100%' }}
width="1000"
height="600"
title="Makerspace Google Calendar"
allowFullScreen
></iframe>
</div>
<CalendarEmbed
src="https://calendar.google.com/calendar/embed?src=195d4999e6906278ce183970e2cf265b0a470d9a35e20e80ac2bd15d5f6f783a%40group.calendar.google.com&ctz=America%2FToronto&mode=WEEK"
title="Digital Makerspace Google Calendar"
calendarUrl="https://calendar.google.com/calendar/u/0?cid=MTk1ZDQ5OTllNjkwNjI3OGNlMTgzOTcwZTJjZjI2NWIwYTQ3MGQ5YTM1ZTIwZTgwYWMyYmQxNWQ1ZjZmNzgzYUBncm91cC5jYWxlbmRhci5nb29nbGUuY29t"
/>

<div className="my-4 p-4 bg-purple-50 rounded-lg">
<h4 className="mb-2">Typical Open Hours</h4>
Expand All @@ -56,17 +106,12 @@ export function CalendarSection() {
<Card>
<CardContent className="p-5">

{/* saboruin calendar */}
<div className="h-[400px] sm:h-screen w-full bg-slate-100 rounded-lg flex items-center justify-center sm:border-2 sm:border-dashed">
<iframe
src="https://calendar.google.com/calendar/embed?src=6975d8476dd6da2953a2d7544ffbe7f08758862eef0fb7bea801de5eee887f4f%40group.calendar.google.com&ctz=America%2FToronto"
style={{ borderWidth: 'solid 1px #777', width: '100%', height: '100%' }}
width="1000"
height="600"
title="Sabourin Makerspace Google Calendar"
allowFullScreen
/>
</div>
{/* sabourin calendar */}
<CalendarEmbed
src="https://calendar.google.com/calendar/embed?src=6975d8476dd6da2953a2d7544ffbe7f08758862eef0fb7bea801de5eee887f4f%40group.calendar.google.com&ctz=America%2FToronto"
title="Sabourin Makerspace Google Calendar"
calendarUrl="https://calendar.google.com/calendar/u/0?cid=Njk3NWQ4NDc2ZGQ2ZGEyOTUzYTJkNzU0NGZmYmU3ZjA4NzU4ODYyZWVmMGZiN2JlYTgwMWRlNWVlZTg4N2Y0ZkBncm91cC5jYWxlbmRhci5nb29nbGUuY29t"
/>

<div className="mt-6 p-4 bg-purple-50 rounded-lg">
<h4 className="mb-2">Typical Open Hours</h4>
Expand Down
Loading