The Ymir Sailing Club PWA (Progressive Web App) is a comprehensive digital solution for managing a sailing club’s boat rental and member management system. Built with modern web technologies, it provides both web and mobile app experiences through a single codebase.
The application uses Astro, a modern static site generator that provides: - Server-Side Rendering (SSR): Pages are rendered on the server for better performance - Component-Based Architecture: Reusable UI components for maintainability - Zero-JavaScript by Default: Only loads JavaScript when needed, improving performance - Multi-Framework Support: Can integrate React, Vue, or Svelte components if needed
The backend uses Netlify Functions, which are serverless functions that: - Auto-Scale: Automatically handle traffic spikes without server management - Event-Driven: Execute code in response to HTTP requests - Cost-Effective: Pay only for actual usage - Global Distribution: Deploy to multiple regions for low latency
The application uses PostgreSQL hosted on Neon: - Relational Database: Structured data storage with relationships between entities - ACID Compliance: Ensures data integrity and consistency - Scalability: Can handle growing amounts of data and users - Cloud-Hosted: Managed database service with automatic backups
Instead of loading a blank page and then filling it with content using JavaScript, SSR generates the complete HTML on the server before sending it to the browser. This means: - Faster Initial Load: Users see content immediately - Better SEO: Search engines can easily read the content - Improved Performance: Less JavaScript needs to be downloaded and executed
A PWA is a web application that behaves like a native mobile app: - Installable: Users can “install” it on their home screen - Offline Capable: Works even without internet connection - Push Notifications: Can send notifications like native apps - Responsive: Adapts to different screen sizes
Instead of running a traditional server 24/7, serverless functions: - Execute on Demand: Only run when called - Auto-Scale: Automatically handle multiple requests - No Server Management: Cloud provider handles infrastructure - Cost-Effective: Pay only for execution time
The system tracks each boat’s current status: - Operational: Available for use - Checked Out: Currently in use by a member - Maintenance: Under repair or maintenance - Out of Service: Temporarily unavailable
// Example: Checking boat availability
const boatStatus = await getBoatStatus(boatId);
if (boatStatus.status === 'operational') {
// Boat is available for checkout
}
Each member has: - Unique Member Number: Primary identifier - Personal Information: Name, phone, email - Authentication: PIN-based login system - Admin Privileges: Some members can access admin features - Sailing History: Track of all boat usage
The system uses a simple PIN-based authentication: - No Passwords: Members use their member number and PIN - Session Management: Maintains login state across page refreshes - Security: PINs are hashed before storage in the database
Each boat has a unique QR code that: - Directs to Checkout Page: QR code contains boat-specific URL - Pre-fills Information: Automatically selects the correct boat - Mobile Optimized: Works seamlessly on mobile devices
The app can send notifications for: - Boat Reminders: Notify when return time is approaching - Overdue Alerts: Alert when boats are overdue - Maintenance Updates: Notify about boat status changes - Club Communications: General announcements
CREATE TABLE members (
PRIMARY KEY,
member_number TEXT NOT NULL,
name TEXT
phone TEXT,
email TEXT,
pin TEXT,BOOLEAN DEFAULT FALSE,
is_admin TIMESTAMP DEFAULT CURRENT_TIMESTAMP
created_at );
CREATE TABLE boats (
id TEXT PRIMARY KEY,
NOT NULL,
name TEXT DEFAULT 'operational',
status TEXT DEFAULT 'individual',
boat_type TEXT TIMESTAMP,
last_maintenance
notes TEXT );
CREATE TABLE check_ins (
id SERIAL PRIMARY KEY,
REFERENCES boats(id),
boat_id TEXT NOT NULL,
sailor_name TEXT REFERENCES members(member_number),
member_number TEXT TIMESTAMP NOT NULL,
departure_time TIMESTAMP,
expected_return TIMESTAMP,
actual_return TIMESTAMP DEFAULT CURRENT_TIMESTAMP
created_at );
POST /api/member-login
- Member authenticationPOST /api/admin-login
- Admin authenticationGET /api/boat-status
- Get boat status and
availabilityPOST /api/check-in
- Check out a boatPOST /api/check-out
- Check in a boatPOST /api/update-boat-status
- Update boat status
(admin)GET /api/members
- Get all membersPOST /api/members
- Create new memberGET /api/profile
- Get member profilePOST /api/push-subscription
- Subscribe to
notificationsPOST /api/cron-notifications
- Trigger scheduled
notificationsA service worker is a background script that: - Caches Resources: Stores files locally for offline access - Handles Notifications: Manages push notifications - Intercepts Requests: Can serve cached content when offline - Background Sync: Can sync data when connection is restored
The manifest file defines how the app behaves when “installed”:
{
"name": "Ymir Sailing Club",
"short_name": "Ymir Sailing",
"description": "Sailing club boat management system",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#2563eb",
"icons": [
{
"src": "/icon-192.svg",
"sizes": "192x192",
"type": "image/svg+xml"
}
]
}
The app can work offline by: - Caching Static Assets: Images, CSS, and JavaScript files - Storing User Data: Member information and preferences - Queueing Actions: Store actions to sync when online - Graceful Degradation: Show appropriate messages when offline
Instead of complex passwords, the system uses: - 3-Digit PINs: Easy to remember and enter on mobile - Hashed Storage: PINs are encrypted before database storage - Session Management: Maintains login state securely - Automatic Logout: Sessions expire after inactivity
The notification system consists of: 1. Frontend Subscription: User subscribes to notifications 2. Database Storage: Subscription details stored securely 3. Server-Side Sending: Server sends notifications via Web Push API 4. Browser Delivery: Browser displays notification to user
// Service Worker - handles incoming notifications
.addEventListener('push', function(event) {
selfconst options = {
body: event.data.text(),
icon: '/icon-192.svg',
badge: '/icon-192.svg',
vibrate: [200, 100, 200],
data: {
dateOfArrival: Date.now(),
primaryKey: 1
};
}
event.waitUntil(
.registration.showNotification('Ymir Sailing Club', options)
self;
); })
The app supports multiple languages through: - Separate Page
Routes: /en/
for English, /is/
for
Icelandic - Language-Specific Content: Different
content for each language - Consistent Navigation:
Language switcher in navigation - Database
Localization: Some content stored in multiple languages
Comprehensive management interface including: - Member Management: Add, edit, and manage club members - Boat Status Control: Update boat availability and maintenance status - Usage Analytics: View boat usage statistics and member activity - Notification Management: Send announcements and manage notifications - Data Export: Export member and usage data
The app is designed mobile-first with: - Flexible Layouts: Adapts to different screen sizes - Touch-Friendly: Large buttons and touch targets - Fast Loading: Optimized for mobile networks - Offline Support: Works without internet connection
The app is hosted on Netlify, which provides: - Global CDN: Fast content delivery worldwide - Automatic Deployments: Deploy on every Git push - SSL Certificates: Automatic HTTPS encryption - Serverless Functions: Backend API endpoints - Form Handling: Built-in form processing
PostgreSQL database hosted on Neon: - Managed Service: No server maintenance required - Automatic Backups: Regular data backups - Scaling: Automatically scales with usage - Security: Enterprise-grade security features
Continuous Integration and Deployment: 1. Code Push: Developer pushes code to GitHub 2. Automatic Build: Netlify builds the application 3. Testing: Automated tests run (if configured) 4. Deployment: Application automatically deploys 5. Monitoring: Monitor deployment success
The Ymir Sailing Club PWA represents a modern approach to club management, combining the best of web and mobile technologies to create a seamless user experience. Built with scalable, maintainable technologies, it provides a solid foundation for future growth and feature additions.