app.js

Download
javascript 263 lines 8.0 KB
  1/**
  2 * Main Application Logic
  3 *
  4 * Initializes router, defines page components, and manages state
  5 */
  6
  7import router from './router.js';
  8
  9// Simple State Management
 10const state = {
 11    user: null,
 12    visitCount: 0,
 13
 14    setUser(user) {
 15        this.user = user;
 16    },
 17
 18    incrementVisit() {
 19        this.visitCount++;
 20    }
 21};
 22
 23// Page Components
 24
 25/**
 26 * Home Page Component
 27 */
 28function HomePage() {
 29    return `
 30        <div class="page-enter">
 31            <h1>Welcome to SPA Router Demo</h1>
 32            <p>This is a demonstration of a simple single-page application using hash-based routing.</p>
 33
 34            <div class="card">
 35                <h2>Features</h2>
 36                <ul>
 37                    <li>Hash-based routing (#/path)</li>
 38                    <li>Dynamic route parameters</li>
 39                    <li>Page transition animations</li>
 40                    <li>Mobile responsive design</li>
 41                    <li>Navigation guards</li>
 42                    <li>404 error handling</li>
 43                </ul>
 44            </div>
 45
 46            <div class="card">
 47                <h2>Getting Started</h2>
 48                <p>Use the navigation bar above to explore different pages:</p>
 49                <ul>
 50                    <li><strong>Home:</strong> You are here!</li>
 51                    <li><strong>About:</strong> Learn more about this project</li>
 52                    <li><strong>Contact:</strong> Fill out a contact form</li>
 53                    <li><strong>User Profile:</strong> View dynamic route parameters</li>
 54                </ul>
 55            </div>
 56
 57            <div class="card">
 58                <h3>Visit Counter</h3>
 59                <p>This page has been loaded <strong>${state.visitCount}</strong> time(s).</p>
 60            </div>
 61
 62            <a href="#/about" class="btn">Learn More</a>
 63        </div>
 64    `;
 65}
 66
 67/**
 68 * About Page Component
 69 */
 70function AboutPage() {
 71    return `
 72        <div class="page-enter">
 73            <h1>About This Project</h1>
 74
 75            <div class="card">
 76                <h2>What is a Single Page Application?</h2>
 77                <p>
 78                    A Single Page Application (SPA) is a web application that loads a single HTML page
 79                    and dynamically updates content as the user interacts with the app. This provides
 80                    a more fluid user experience similar to desktop applications.
 81                </p>
 82            </div>
 83
 84            <div class="card">
 85                <h2>Hash-Based Routing</h2>
 86                <p>
 87                    This implementation uses hash-based routing (<code>#/path</code>), which:
 88                </p>
 89                <ul>
 90                    <li>Works without server configuration</li>
 91                    <li>Doesn't trigger page reloads</li>
 92                    <li>Maintains browser history</li>
 93                    <li>Enables back/forward navigation</li>
 94                </ul>
 95            </div>
 96
 97            <div class="card">
 98                <h2>Technology Stack</h2>
 99                <ul>
100                    <li><strong>HTML5:</strong> Semantic markup</li>
101                    <li><strong>CSS3:</strong> Custom properties, animations, flexbox</li>
102                    <li><strong>JavaScript ES6+:</strong> Modules, classes, async/await</li>
103                    <li><strong>No Framework:</strong> Pure vanilla JavaScript</li>
104                </ul>
105            </div>
106
107            <a href="#/contact" class="btn btn-secondary">Get in Touch</a>
108        </div>
109    `;
110}
111
112/**
113 * Contact Page Component
114 */
115function ContactPage() {
116    // Add form submission handler after render
117    setTimeout(() => {
118        const form = document.getElementById('contact-form');
119        if (form) {
120            form.addEventListener('submit', handleContactSubmit);
121        }
122    }, 0);
123
124    return `
125        <div class="page-enter">
126            <h1>Contact Us</h1>
127            <p>Have questions? Fill out the form below and we'll get back to you.</p>
128
129            <form id="contact-form" class="card">
130                <div class="form-group">
131                    <label class="form-label" for="name">Name:</label>
132                    <input type="text" id="name" name="name" class="form-control" required>
133                </div>
134
135                <div class="form-group">
136                    <label class="form-label" for="email">Email:</label>
137                    <input type="email" id="email" name="email" class="form-control" required>
138                </div>
139
140                <div class="form-group">
141                    <label class="form-label" for="message">Message:</label>
142                    <textarea id="message" name="message" rows="5" class="form-control" required></textarea>
143                </div>
144
145                <button type="submit" class="btn">Send Message</button>
146            </form>
147
148            <div id="form-result" style="margin-top: 1rem;"></div>
149        </div>
150    `;
151}
152
153/**
154 * User Profile Page Component (Dynamic Route)
155 */
156function UserProfilePage(params) {
157    const userId = params.id || 'unknown';
158
159    // Simulate user data
160    const userData = {
161        '123': { name: 'John Doe', email: 'john@example.com', role: 'Developer' },
162        '456': { name: 'Jane Smith', email: 'jane@example.com', role: 'Designer' },
163        'unknown': { name: 'Guest User', email: 'N/A', role: 'Visitor' }
164    };
165
166    const user = userData[userId] || userData['unknown'];
167
168    return `
169        <div class="page-enter">
170            <h1>User Profile</h1>
171
172            <div class="card">
173                <h2>${user.name}</h2>
174                <p><strong>User ID:</strong> ${userId}</p>
175                <p><strong>Email:</strong> ${user.email}</p>
176                <p><strong>Role:</strong> ${user.role}</p>
177            </div>
178
179            <div class="card">
180                <h3>Dynamic Route Parameters</h3>
181                <p>This page demonstrates dynamic routing. The URL pattern is <code>/user/:id</code></p>
182                <p>Current route: <code>/user/${userId}</code></p>
183                <p>Try different user IDs:</p>
184                <ul>
185                    <li><a href="#/user/123">/user/123</a> - John Doe</li>
186                    <li><a href="#/user/456">/user/456</a> - Jane Smith</li>
187                    <li><a href="#/user/789">/user/789</a> - Unknown user</li>
188                </ul>
189            </div>
190
191            <a href="#/" class="btn">Back to Home</a>
192        </div>
193    `;
194}
195
196/**
197 * 404 Not Found Page
198 */
199function NotFoundPage() {
200    return `
201        <div class="page-enter">
202            <h1>404 - Page Not Found</h1>
203            <p>The page you're looking for doesn't exist.</p>
204            <a href="#/" class="btn">Go Home</a>
205        </div>
206    `;
207}
208
209// Event Handlers
210
211function handleContactSubmit(e) {
212    e.preventDefault();
213
214    const formData = {
215        name: document.getElementById('name').value,
216        email: document.getElementById('email').value,
217        message: document.getElementById('message').value
218    };
219
220    // Simulate form submission
221    const resultDiv = document.getElementById('form-result');
222    resultDiv.innerHTML = `
223        <div class="card" style="border-left-color: #2ecc71;">
224            <h3>Thank you, ${formData.name}!</h3>
225            <p>Your message has been received. We'll respond to ${formData.email} soon.</p>
226        </div>
227    `;
228
229    // Reset form
230    document.getElementById('contact-form').reset();
231}
232
233// Router Configuration
234
235// Register routes
236router.addRoute('/', HomePage);
237router.addRoute('/about', AboutPage);
238router.addRoute('/contact', ContactPage);
239router.addRoute('/user/:id', UserProfilePage);
240
241// Set 404 handler
242router.setNotFound(NotFoundPage);
243
244// Navigation guards
245router.beforeEach((path) => {
246    console.log('Navigating to:', path);
247    state.incrementVisit();
248    return true; // Continue navigation
249});
250
251router.afterEach((path, params) => {
252    console.log('Navigation complete:', path, params);
253    // Update page title
254    const titles = {
255        '/': 'Home',
256        '/about': 'About',
257        '/contact': 'Contact',
258    };
259    document.title = `SPA Example - ${titles[path] || 'Page'}`;
260});
261
262console.log('App initialized successfully');