source: interfejs/register.html@ 4dff800

finki-main main
Last change on this file since 4dff800 was 69f2a41, checked in by Klimentina Efremova <klimentina08642@…>, 7 months ago

Initial commit

  • Property mode set to 100644
File size: 10.5 KB
Line 
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Register as Client - Handcraft Marketplace</title>
7 <link rel="stylesheet" href="style.css">
8</head>
9<body>
10<header>
11 <div class="logo-container">
12 <img src="../images/administrative/logo.jpg" alt="Handcraft Marketplace Logo" onerror="this.style.display='none'">
13 <h1>🎨 Handcraft Marketplace</h1>
14 </div>
15 <nav>
16 <ul>
17 <li><a href="index.html">Home</a></li>
18 <li><a href="products.html">Products</a></li>
19 <li><a href="login.html">Login</a></li>
20 <li><a href="register.html" class="active">Register</a></li>
21 <li><a href="register-store.html">Open Store</a></li>
22 </ul>
23 </nav>
24</header>
25
26<main>
27 <div class="form-container">
28 <h2>Create Client Account</h2>
29 <p class="form-subtitle">Join as a buyer to shop from our artisans</p>
30
31 <form id="register-form" class="form">
32 <div class="form-row">
33 <div class="form-group">
34 <label for="first-name">First Name *</label>
35 <input type="text" id="first-name" name="first-name" required>
36 </div>
37
38 <div class="form-group">
39 <label for="last-name">Last Name *</label>
40 <input type="text" id="last-name" name="last-name" required>
41 </div>
42 </div>
43
44 <div class="form-group">
45 <label for="email">Email *</label>
46 <input type="email" id="email" name="email" required>
47 </div>
48
49 <div class="form-group">
50 <label for="password">Password *</label>
51 <input type="password" id="password" name="password" required>
52 <small class="password-hint">At least 8 characters with uppercase, lowercase, number, and special character</small>
53 </div>
54
55 <div class="form-group">
56 <label for="confirm-password">Confirm Password *</label>
57 <input type="password" id="confirm-password" name="confirm-password" required>
58 </div>
59
60 <h3>Delivery Address (Optional)</h3>
61 <p class="form-note">You can add delivery addresses later in your dashboard</p>
62
63 <div class="form-group">
64 <label for="address">Street Address</label>
65 <input type="text" id="address" name="address" placeholder="st. Center num.10">
66 </div>
67
68 <div class="form-row">
69 <div class="form-group">
70 <label for="city">City</label>
71 <input type="text" id="city" name="city" placeholder="Skopje">
72 </div>
73 <div class="form-group">
74 <label for="postcode">Postcode</label>
75 <input type="text" id="postcode" name="postcode" placeholder="1000">
76 </div>
77 </div>
78
79 <div class="form-group">
80 <label for="country">Country</label>
81 <input type="text" id="country" name="country" placeholder="North Macedonia">
82 </div>
83
84 <div class="form-group checkbox">
85 <input type="checkbox" id="is-default-address" name="is-default-address" checked>
86 <label for="is-default-address">Set as default delivery address</label>
87 </div>
88
89 <div class="form-group">
90 <button type="submit" class="btn-primary btn-full">Register</button>
91 </div>
92 </form>
93
94 <div class="form-footer">
95 <p>Already have an account? <a href="login.html">Login here</a></p>
96 <p>Want to sell your products? <a href="register-store.html">Register as a store owner</a></p>
97 </div>
98 </div>
99</main>
100
101<div id="verification-modal" class="modal" style="display: none;">
102 <div class="modal-content">
103 <span class="close">&times;</span>
104 <h2>Verify Your Email</h2>
105 <p>We've sent a verification code to <span id="verification-email"></span></p>
106 <p class="code-expiry">Code expires in 30 seconds</p>
107 <div class="form-group">
108 <label for="verification-code">Enter 6-digit code:</label>
109 <input type="text" id="verification-code" maxlength="6" placeholder="000000">
110 </div>
111 <div class="form-group">
112 <button id="verify-code-btn" class="btn-primary">Verify & Complete Registration</button>
113 </div>
114 <p class="resend-link">Didn't receive code? <a href="#" id="resend-code">Resend</a></p>
115 <p class="resend-link">Time remaining: <span id="countdown">30</span> seconds</p>
116 </div>
117</div>
118
119<footer>
120 <div class="footer-content">
121 <div class="footer-section">
122 <h3>Handcraft Marketplace</h3>
123 <p>Connecting artisans with buyers worldwide</p>
124 </div>
125 <div class="footer-section">
126 <h3>Quick Links</h3>
127 <ul>
128 <li><a href="index.html">Home</a></li>
129 <li><a href="products.html">Products</a></li>
130 <li><a href="login.html">Login</a></li>
131 <li><a href="register.html">Register</a></li>
132 </ul>
133 </div>
134 <div class="footer-section">
135 <h3>For Sellers</h3>
136 <ul>
137 <li><a href="register-store.html">Open a Store</a></li>
138 <li><a href="#">Seller Guidelines</a></li>
139 <li><a href="#">Pricing</a></li>
140 </ul>
141 </div>
142 <div class="footer-section">
143 <h3>Contact</h3>
144 <p>Email: support@handcraft.com</p>
145 <p>Phone: +1 (555) 123-4567</p>
146 </div>
147 </div>
148 <div class="footer-bottom">
149 <p>&copy; 2025 Handcraft Marketplace. All rights reserved.</p>
150 </div>
151</footer>
152
153<script src="script.js"></script>
154<script>
155 document.addEventListener('DOMContentLoaded', () => {
156 const registerForm = document.getElementById('register-form');
157 const modal = document.getElementById('verification-modal');
158 const closeBtn = document.querySelector('.close');
159 const verifyBtn = document.getElementById('verify-code-btn');
160 const resendLink = document.getElementById('resend-code');
161 const verificationCode = document.getElementById('verification-code');
162 const countdownEl = document.getElementById('countdown');
163 let currentEmail = '';
164 let countdownInterval;
165
166 function startCountdown(seconds) {
167 if (countdownInterval) clearInterval(countdownInterval);
168 countdownEl.textContent = seconds;
169 countdownInterval = setInterval(() => {
170 let current = parseInt(countdownEl.textContent);
171 if (current <= 1) {
172 clearInterval(countdownInterval);
173 countdownEl.textContent = '0';
174 } else {
175 countdownEl.textContent = current - 1;
176 }
177 }, 1000);
178 }
179
180 registerForm.addEventListener('submit', async (e) => {
181 e.preventDefault();
182
183 const password = document.getElementById('password').value;
184 const confirmPassword = document.getElementById('confirm-password').value;
185
186 if (password !== confirmPassword) {
187 alert('Passwords do not match');
188 return;
189 }
190
191 // Password validation
192 const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
193 if (!passwordRegex.test(password)) {
194 alert('Password must have at least 8 characters, including uppercase, lowercase, number and special character');
195 return;
196 }
197
198 const formData = {
199 firstName: document.getElementById('first-name').value,
200 lastName: document.getElementById('last-name').value,
201 email: document.getElementById('email').value,
202 password: password,
203 address: document.getElementById('address').value || null,
204 city: document.getElementById('city').value || null,
205 postcode: document.getElementById('postcode').value || null,
206 country: document.getElementById('country').value || null,
207 isDefaultAddress: document.getElementById('is-default-address').checked
208 };
209
210 try {
211 const response = await fetch('/api/client-register', {
212 method: 'POST',
213 headers: { 'Content-Type': 'application/json' },
214 body: JSON.stringify(formData)
215 });
216
217 const data = await response.json();
218
219 if (data.success) {
220 currentEmail = data.email;
221 document.getElementById('verification-email').textContent = currentEmail;
222 modal.style.display = 'block';
223 startCountdown(30);
224
225 if (data.developmentCode) {
226 console.log('🔐 Development verification code:', data.developmentCode);
227 // Auto-fill for development
228 verificationCode.value = data.developmentCode;
229 }
230 } else {
231 alert(data.message || 'Registration failed');
232 }
233 } catch (error) {
234 console.error('Registration error:', error);
235 alert('An error occurred during registration');
236 }
237 });
238
239 verifyBtn.addEventListener('click', async () => {
240 const code = verificationCode.value;
241
242 if (!code || code.length !== 6) {
243 alert('Please enter a valid 6-digit code');
244 return;
245 }
246
247 try {
248 const response = await fetch('/api/verify-email', {
249 method: 'POST',
250 headers: { 'Content-Type': 'application/json' },
251 body: JSON.stringify({
252 email: currentEmail,
253 code: code
254 })
255 });
256
257 const data = await response.json();
258
259 if (data.success) {
260 clearInterval(countdownInterval);
261 alert('Registration successful! You can now login.');
262 window.location.href = data.redirectTo || 'login.html';
263 } else {
264 alert(data.message || 'Verification failed');
265 }
266 } catch (error) {
267 console.error('Verification error:', error);
268 alert('An error occurred during verification');
269 }
270 });
271
272 resendLink.addEventListener('click', async (e) => {
273 e.preventDefault();
274
275 try {
276 const response = await fetch('/api/resend-verification', {
277 method: 'POST',
278 headers: { 'Content-Type': 'application/json' },
279 body: JSON.stringify({ email: currentEmail })
280 });
281
282 const data = await response.json();
283
284 if (data.success) {
285 alert('New verification code sent!');
286 startCountdown(30);
287 if (data.developmentCode) {
288 console.log('🔐 New development code:', data.developmentCode);
289 verificationCode.value = data.developmentCode;
290 }
291 } else {
292 alert(data.message || 'Failed to resend code');
293 }
294 } catch (error) {
295 console.error('Resend error:', error);
296 alert('An error occurred');
297 }
298 });
299
300 closeBtn.addEventListener('click', () => {
301 modal.style.display = 'none';
302 clearInterval(countdownInterval);
303 });
304
305 window.addEventListener('click', (event) => {
306 if (event.target === modal) {
307 modal.style.display = 'none';
308 clearInterval(countdownInterval);
309 }
310 });
311 });
312</script>
313</body>
314</html>
Note: See TracBrowser for help on using the repository browser.