The official website for the UNSW Robotics and Mechatronics Society (RAMSoc) - a student-run engineering society that provides Mechatronic Engineering opportunities and pathways between students and the professional community.
- Modern Tech Stack: Built with Next.js 15, React 19, and TypeScript
- Responsive Design: Optimized for all devices using Tailwind CSS v4
- Dynamic Content: Integration with Contentful CMS and Notion API
- Interactive Components: Smooth animations with Motion One
- Career Portal: Job listings with real-time data from Notion
- Events System: Showcase of past and upcoming events
- Team Showcase: Dynamic team member profiles by year
- Type-Safe APIs: tRPC for end-to-end type safety
- Framework: Next.js 15 with App Router
- Language: TypeScript 5.7
- Styling: Tailwind CSS v4 + SCSS modules
- UI Components: Radix UI primitives
- Animations: Motion One & Framer Motion
- Icons: Lucide React
- Forms: React Hook Form (planned)
Using T3 Stack as a base template
- API Layer: tRPC for type-safe APIs
- CMS: Contentful for content management
- Database: Notion API for career listings
- State Management: TanStack Query (React Query)
- HTTP Client: Axios
- Package Manager: Yarn 1.22+
- Linting: ESLint 9 with Next.js config
- Code Formatting: Prettier with Tailwind plugin
- Deployment: Vercel
- Build Tool: Turbopack (Next.js 15)
Follow these steps to set up the project locally:
-
Clone the repository
git clone https://github.com/UNSW-Robotics-and-Mechatronics-Society/ramsoc-website.git cd ramsoc-website -
Install dependencies
yarn install
-
Set up environment variables
Option A: Using Vercel CLI (Recommended)
If you have access to the RAMSoc Vercel project, you can pull environment variables directly:
# Install Vercel CLI globally (if not already installed) npm install -g vercel # Login to Vercel using RAMSoc's Google account vercel login # Note: Sign in with the RAMSoc Google account when prompted # Link your local project to the Vercel project vercel link # When prompted, select: # - Scope: "ramsoc-unsws-projects" # - Project: "ramsoc-website" # Pull environment variables for development vercel env pull .env.local
This will automatically create a
.env.localfile with all required environment variables.Option B: Manual Setup
Create a
.env.localfile in the root directory:# Contentful CONTENTFUL_SPACE_ID=your_contentful_space_id CONTENTFUL_ACCESS_TOKEN=your_contentful_access_token # Notion NOTION_TOKEN=your_notion_integration_token NEXT_PUBLIC_NOTION_CAREERS_DB_ID=your_careers_database_id
Ask the team for the actual values of these environment variables.
-
Start the development server
yarn dev
The website will be available at
http://localhost:3000
src/
βββ app/ # Next.js App Router
β βββ _components/ # Homepage components
β βββ api/ # API routes (tRPC, Notion)
β βββ careers/ # Career portal with Notion integration
β βββ events/ # Events page
β βββ team/ # Team showcase by year
β βββ layout.tsx # Root layout
β βββ page.tsx # Homepage
β βββ providers.tsx # React Query & context providers
βββ components/ # Reusable UI components
β βββ ui/ # Base UI components (Button, Container, etc.)
βββ features/ # Feature-specific components & logic
β βββ careers/ # Career-related components & logic
β βββ events/ # Event-related components & logic
β βββ team/ # Team-related components & logic
βββ hooks/ # Custom React hooks
βββ lib/ # Utility libraries & helpers
β βββ contentful/ # Contentful CMS client
β βββ utils.ts # Shared utilities (cn, etc.)
β βββ constants/ # App constants
βββ server/ # Server-side code
β βββ api/ # tRPC routers & procedures
βββ styles/ # Global styles
β βββ globals.css # Tailwind imports & global CSS
βββ trpc/ # tRPC client configurationyarn dev- Start development server with Turbopackyarn build- Build for productionyarn start- Start production serveryarn lint- Run ESLintyarn check-types- Type checking with TypeScript
yarn pages:build- Build for Vercelyarn preview- Preview Vercel build locally
Note: Deployment is handled automatically via Vercel on pushes to the
mainbranch.
The website uses Contentful as a headless CMS for managing:
- Event information and details
- Team member profiles and bios
- General content and assets
Career listings are managed through Notion databases, providing:
- Easy content management for non-technical users
- Rich text editing with Notion's block editor
- Structured data for job postings
- Real-time updates without redeployment
/api/events- Fetch events from Contentful/api/notion/db/[slug]- Query Notion databases/api/notion/page/[slug]- Fetch individual Notion pages
/api/trpc/[trpc]- Type-safe tRPC API endpoints
- Interactive Job Listings: Browse available positions with filtering
- Modal Overlays: Detailed job descriptions using Notion rendering
- Real-time Data: Direct integration with Notion database
- Quick Apply: Direct application links with URL normalization
- Responsive Design: Optimized for mobile and desktop
- Loading States: Skeleton loaders and React Query caching
- Keyboard Accessible: Full keyboard navigation support
- Dynamic Event Cards: Large and small card variations
- Loading States: Skeleton components for smooth UX
- Past and Current Events: Automatic separation by date
- Contentful Integration: Easy content updates via CMS
- Image Optimization: Next.js Image component for performance
- Year-based Navigation: Browse teams by academic year
- Profile Cards: Interactive member profiles with hover effects
- Subcommittee Organization: Grouped by role and responsibility
- Social Links: LinkedIn and other profile links
- Responsive Grid: Adaptive layout for all screen sizes
The website is deployed on Vercel with automatic deployments from the main branch.
- Build command:
yarn pages:build - Output directory:
.vercel/output/static - Node version: 20.x
- Framework: Next.js (Static Export)
Ensure all required environment variables are set in your Vercel dashboard:
Required:
CONTENTFUL_SPACE_ID- Contentful space identifierCONTENTFUL_ACCESS_TOKEN- Contentful API access tokenNOTION_TOKEN- Notion integration tokenNEXT_PUBLIC_NOTION_CAREERS_DB_ID- Public Notion database ID for careers
- Production:
mainbranch β ramsocunsw.org - Preview: All other branches get preview deployments
We welcome contributions from RAMSoc members and the community!
- Fork the repository
- Create a feature branch (
git checkout -b feat/amazing-feature) - Make your changes
- Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feat/amazing-feature) - Open a Pull Request
We follow Conventional Commits:
feat:- New featuresfix:- Bug fixesdocs:- Documentation changesstyle:- Code style changes (formatting, etc.)refactor:- Code refactoringtest:- Adding or updating testschore:- Maintenance tasks
- Follow existing TypeScript and React patterns
- Use Prettier for code formatting (auto-format on save)
- Ensure ESLint passes before submitting (
yarn lint) - Run type checking (
yarn check-types) - Write meaningful commit messages
- Keep components focused and reusable
- Use Tailwind CSS utilities over custom CSS when possible
- Convert
@applydirectives to regular CSS in SCSS modules
- Modern CSS features with
@themeand custom properties - Better performance with optimized CSS output
- Improved developer experience with better error messages
- Future-proof with CSS-first approach
Tailwind v4 requires @reference directive for @apply in CSS modules, which causes linting issues. We convert @apply rules to regular CSS for:
- Better compatibility across tools
- Explicit CSS values (easier to debug)
- No processing overhead
- Consistent with Tailwind v4 best practices
- End-to-end type safety from server to client
- No code generation required
- Automatic TypeScript inference
- Better DX with autocomplete and type errors
- Automatic caching and background refetching
- Optimistic updates
- Request deduplication
- Built-in loading and error states
- Great DevTools for debugging
This project is private and belongs to the UNSW Robotics and Mechatronics Society.
For questions or support:
- Website: ramsocunsw.org
- Email: technical@ramsocunsw.org
- GitHub: UNSW-Robotics-and-Mechatronics-Society
Built with β€οΈ by the RAMSoc team at UNSW