source: interfejs/register-store.html@ 591278c

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

Initial commit

  • Property mode set to 100644
File size: 21.9 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 Your Store - 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">Register</a></li>
21 <li><a href="register-store.html" class="active">Open Store</a></li>
22 </ul>
23 </nav>
24</header>
25
26<main>
27 <div class="form-container form-container-large">
28 <div class="form-header">
29 <h2>Open Your Handcraft Store</h2>
30 <p class="form-subtitle">Join our community of artisans and start selling your handmade creations</p>
31 </div>
32
33 <div class="store-benefits">
34 <div class="benefit-badge">
35 <span class="benefit-icon">🌍</span>
36 <span>Global Reach</span>
37 </div>
38 <div class="benefit-badge">
39 <span class="benefit-icon">💳</span>
40 <span>Secure Payments</span>
41 </div>
42 <div class="benefit-badge">
43 <span class="benefit-icon">📦</span>
44 <span>Shipping Support</span>
45 </div>
46 <div class="benefit-badge">
47 <span class="benefit-icon">📊</span>
48 <span>Sales Analytics</span>
49 </div>
50 </div>
51
52 <form id="store-register-form" class="form">
53 <div class="form-section">
54 <h3>Store Owner Information</h3>
55 <p class="section-note">This will be your account information</p>
56
57 <div class="form-row">
58 <div class="form-group">
59 <label for="owner-first-name">First Name *</label>
60 <input type="text" id="owner-first-name" name="owner-first-name" placeholder="Anna" required>
61 </div>
62
63 <div class="form-group">
64 <label for="owner-last-name">Last Name *</label>
65 <input type="text" id="owner-last-name" name="owner-last-name" placeholder="Ivanova" required>
66 </div>
67 </div>
68
69 <div class="form-group">
70 <label for="owner-ssn">Social Security Number (13 digits) *</label>
71 <input type="text" id="owner-ssn" name="owner-ssn" maxlength="13" pattern="\d{13}" placeholder="1234567890123" required>
72 <small class="input-hint">Exactly 13 digits, no spaces or dashes</small>
73 </div>
74
75 <div class="form-group">
76 <label for="owner-email">Personal Email *</label>
77 <input type="email" id="owner-email" name="owner-email" placeholder="anna@email.com" required>
78 <small class="input-hint">We'll send verification code to this email</small>
79 </div>
80 </div>
81
82 <div class="form-section">
83 <h3>Store Information</h3>
84 <p class="section-note">Tell us about your store</p>
85
86 <div class="form-group">
87 <label for="store-name">Store Name *</label>
88 <input type="text" id="store-name" name="store-name" placeholder="HandCraft001" required>
89 </div>
90
91 <div class="form-group">
92 <label for="store-address">Physical Address *</label>
93 <input type="text" id="store-address" name="store-address" placeholder="st. Main num.5, Skopje 1000, North Macedonia" required>
94 <small class="input-hint">Format: street name, number, city postcode, country</small>
95 </div>
96
97 <div class="form-group">
98 <label for="store-email">Store Email *</label>
99 <input type="email" id="store-email" name="store-email" placeholder="store@handcraft.com" required>
100 <small class="input-hint">This will be the official store contact email</small>
101 </div>
102
103 <div class="form-group">
104 <label for="store-founding-date">Date of Founding *</label>
105 <input type="date" id="store-founding-date" name="store-founding-date" required>
106 </div>
107
108 <div class="form-group">
109 <label for="store-description">Store Description</label>
110 <textarea id="store-description" name="store-description" rows="4" placeholder="Tell customers about your store, what kind of products you make, your story..."></textarea>
111 </div>
112 </div>
113
114 <div class="form-section">
115 <h3>Account Security</h3>
116 <p class="section-note">Create a strong password for your account</p>
117
118 <div class="form-group">
119 <label for="password">Password *</label>
120 <input type="password" id="password" name="password" required>
121 <small class="password-hint">At least 8 characters with uppercase, lowercase, number, and special character</small>
122 </div>
123
124 <div class="form-group">
125 <label for="confirm-password">Confirm Password *</label>
126 <input type="password" id="confirm-password" name="confirm-password" required>
127 </div>
128
129 <div class="form-group">
130 <label for="signature">Your Signature *</label>
131 <input type="text" id="signature" name="signature" placeholder="e.g., A.Ivanova or Anna Ivanova" required>
132 <small class="input-hint">This signature will appear on official documents and reports</small>
133 </div>
134 </div>
135
136 <div class="form-section terms-section">
137 <div class="form-group checkbox">
138 <input type="checkbox" id="terms" name="terms" required>
139 <label for="terms">I agree to the <a href="#" target="_blank">Terms of Service</a> and <a href="#" target="_blank">Seller Agreement</a> *</label>
140 </div>
141
142 <div class="form-group checkbox">
143 <input type="checkbox" id="privacy" name="privacy" required>
144 <label for="privacy">I acknowledge that my store information will be processed according to the <a href="#" target="_blank">Privacy Policy</a> *</label>
145 </div>
146
147 <div class="form-group checkbox">
148 <input type="checkbox" id="communications" name="communications">
149 <label for="communications">I'd like to receive tips and updates about selling on Handcraft Marketplace</label>
150 </div>
151 </div>
152
153 <div class="form-group">
154 <button type="submit" class="btn-primary btn-full btn-large">Register My Store</button>
155 </div>
156 </form>
157
158 <div class="form-footer">
159 <p>Already have a store? <a href="login.html">Login to your account</a></p>
160 <p>Want to shop instead? <a href="register.html">Register as a client</a></p>
161 <p>Need help? <a href="request-access.html">Contact support</a></p>
162 </div>
163 </div>
164</main>
165
166<div id="verification-modal" class="modal" style="display: none;">
167 <div class="modal-content">
168 <span class="close">&times;</span>
169 <h2>Verify Your Email</h2>
170 <p>We've sent a verification code to <strong><span id="verification-email"></span></strong></p>
171 <p>for store: <strong><span id="verification-store"></span></strong></p>
172 <div class="verification-info">
173 <p class="code-expiry">⚠️ Code expires in <span id="countdown">30</span> seconds</p>
174 <p>Please check your email (including spam folder) for the 6-digit code.</p>
175 </div>
176 <div class="form-group">
177 <label for="verification-code">Enter 6-digit verification code:</label>
178 <input type="text" id="verification-code" maxlength="6" placeholder="000000" autocomplete="off">
179 </div>
180 <div class="form-group">
181 <button id="verify-code-btn" class="btn-primary btn-full">Verify & Complete Registration</button>
182 </div>
183 <div class="verification-footer">
184 <p class="resend-link">Didn't receive code? <a href="#" id="resend-code">Resend verification code</a></p>
185 <p class="change-email-link">Wrong email? <a href="#" id="change-email">Go back and change</a></p>
186 </div>
187 </div>
188</div>
189
190<div id="success-modal" class="modal" style="display: none;">
191 <div class="modal-content success-content">
192 <span class="close">&times;</span>
193 <div class="success-icon">✓</div>
194 <h2>Store Registration Successful!</h2>
195 <p>Congratulations! Your store has been created.</p>
196
197 <div class="success-details">
198 <p><strong>Store ID:</strong> <span id="success-store-id"></span></p>
199 <p><strong>Store Name:</strong> <span id="success-store-name"></span></p>
200 <p><strong>Owner ID:</strong> <span id="success-owner-id"></span></p>
201 </div>
202
203 <p class="success-note">Please save your Store ID and Owner ID for future reference.</p>
204 <p class="success-note">You can now login with your email and password.</p>
205
206 <div style="margin-top: 2rem;">
207 <a href="login.html" class="btn-primary">Go to Login</a>
208 <a href="index.html" class="btn-secondary">Return to Home</a>
209 </div>
210 </div>
211</div>
212
213<footer>
214 <div class="footer-content">
215 <div class="footer-section">
216 <h3>Handcraft Marketplace</h3>
217 <p>Start your selling journey today</p>
218 </div>
219 <div class="footer-section">
220 <h3>Seller Resources</h3>
221 <ul>
222 <li><a href="#">Seller Guidelines</a></li>
223 <li><a href="#">Pricing & Fees</a></li>
224 <li><a href="#">Success Stories</a></li>
225 <li><a href="#">Seller Support</a></li>
226 </ul>
227 </div>
228 <div class="footer-section">
229 <h3>Quick Links</h3>
230 <ul>
231 <li><a href="index.html">Home</a></li>
232 <li><a href="products.html">Products</a></li>
233 <li><a href="login.html">Login</a></li>
234 </ul>
235 </div>
236 </div>
237 <div class="footer-bottom">
238 <p>&copy; 2025 Handcraft Marketplace. All rights reserved.</p>
239 </div>
240</footer>
241
242<script src="script.js"></script>
243<script>
244 document.addEventListener('DOMContentLoaded', () => {
245 const registerForm = document.getElementById('store-register-form');
246 const modal = document.getElementById('verification-modal');
247 const successModal = document.getElementById('success-modal');
248 const closeBtns = document.querySelectorAll('.close');
249 const verifyBtn = document.getElementById('verify-code-btn');
250 const resendLink = document.getElementById('resend-code');
251 const changeEmailLink = document.getElementById('change-email');
252 const verificationCode = document.getElementById('verification-code');
253 const countdownEl = document.getElementById('countdown');
254
255 let currentEmail = '';
256 let currentStoreName = '';
257 let countdownInterval;
258
259 function startCountdown(seconds) {
260 if (countdownInterval) clearInterval(countdownInterval);
261 countdownEl.textContent = seconds;
262 countdownInterval = setInterval(() => {
263 let current = parseInt(countdownEl.textContent);
264 if (current <= 1) {
265 clearInterval(countdownInterval);
266 countdownEl.textContent = '0';
267 } else {
268 countdownEl.textContent = current - 1;
269 }
270 }, 1000);
271 }
272
273 // Password validation function
274 function validatePassword(password) {
275 const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
276 return passwordRegex.test(password);
277 }
278
279 registerForm.addEventListener('submit', async (e) => {
280 e.preventDefault();
281
282 // Get form values
283 const ownerFirstName = document.getElementById('owner-first-name').value;
284 const ownerLastName = document.getElementById('owner-last-name').value;
285 const ownerSSN = document.getElementById('owner-ssn').value;
286 const ownerEmail = document.getElementById('owner-email').value;
287 const storeName = document.getElementById('store-name').value;
288 const storeAddress = document.getElementById('store-address').value;
289 const storeEmail = document.getElementById('store-email').value;
290 const storeFoundingDate = document.getElementById('store-founding-date').value;
291 const password = document.getElementById('password').value;
292 const confirmPassword = document.getElementById('confirm-password').value;
293 const signature = document.getElementById('signature').value;
294
295 // Validate required fields
296 if (!ownerFirstName || !ownerLastName || !ownerSSN || !ownerEmail ||
297 !storeName || !storeAddress || !storeEmail || !storeFoundingDate ||
298 !password || !confirmPassword || !signature) {
299 alert('Please fill in all required fields');
300 return;
301 }
302
303 // Validate SSN
304 if (!/^\d{13}$/.test(ownerSSN)) {
305 alert('SSN must be exactly 13 digits');
306 return;
307 }
308
309 // Validate email format
310 const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
311 if (!emailRegex.test(ownerEmail)) {
312 alert('Please enter a valid personal email address');
313 return;
314 }
315 if (!emailRegex.test(storeEmail)) {
316 alert('Please enter a valid store email address');
317 return;
318 }
319
320 // Validate passwords match
321 if (password !== confirmPassword) {
322 alert('Passwords do not match');
323 return;
324 }
325
326 // Validate password strength
327 if (!validatePassword(password)) {
328 alert('Password must have at least 8 characters, including uppercase, lowercase, number and special character');
329 return;
330 }
331
332 // Validate terms
333 if (!document.getElementById('terms').checked || !document.getElementById('privacy').checked) {
334 alert('You must agree to the Terms of Service and Privacy Policy');
335 return;
336 }
337
338 // Validate founding date is not in future
339 const foundingDate = new Date(storeFoundingDate);
340 const today = new Date();
341 if (foundingDate > today) {
342 alert('Date of founding cannot be in the future');
343 return;
344 }
345
346 const formData = {
347 ownerFirstName,
348 ownerLastName,
349 ownerSSN,
350 ownerEmail,
351 storeName,
352 storeAddress,
353 storeEmail,
354 storeFoundingDate,
355 storeDescription: document.getElementById('store-description').value,
356 password,
357 confirmPassword,
358 signature
359 };
360
361 try {
362 const response = await fetch('/api/register-store', {
363 method: 'POST',
364 headers: { 'Content-Type': 'application/json' },
365 body: JSON.stringify(formData)
366 });
367
368 const data = await response.json();
369
370 if (data.success) {
371 currentEmail = data.email;
372 currentStoreName = data.storeName;
373 document.getElementById('verification-email').textContent = currentEmail;
374 document.getElementById('verification-store').textContent = currentStoreName;
375 modal.style.display = 'block';
376 startCountdown(30);
377
378 if (data.developmentCode) {
379 console.log('🔐 Development verification code:', data.developmentCode);
380 // Auto-fill for development
381 verificationCode.value = data.developmentCode;
382 }
383 } else {
384 alert(data.message || 'Registration failed');
385 }
386 } catch (error) {
387 console.error('Registration error:', error);
388 alert('An error occurred during registration');
389 }
390 });
391
392 verifyBtn.addEventListener('click', async () => {
393 const code = verificationCode.value;
394
395 if (!code || code.length !== 6) {
396 alert('Please enter a valid 6-digit code');
397 return;
398 }
399
400 try {
401 const response = await fetch('/api/verify-email', {
402 method: 'POST',
403 headers: { 'Content-Type': 'application/json' },
404 body: JSON.stringify({
405 email: currentEmail,
406 code: code
407 })
408 });
409
410 const data = await response.json();
411
412 if (data.success) {
413 clearInterval(countdownInterval);
414 modal.style.display = 'none';
415
416 // Show success modal with store details
417 document.getElementById('success-store-id').textContent = data.storeIdPadded || data.storeId;
418 document.getElementById('success-store-name').textContent = data.storeName;
419 document.getElementById('success-owner-id').textContent = data.personalId;
420
421 successModal.style.display = 'block';
422
423 // Reset form
424 registerForm.reset();
425 } else {
426 alert(data.message || 'Verification failed');
427 }
428 } catch (error) {
429 console.error('Verification error:', error);
430 alert('An error occurred during verification');
431 }
432 });
433
434 resendLink.addEventListener('click', async (e) => {
435 e.preventDefault();
436
437 try {
438 const response = await fetch('/api/resend-verification', {
439 method: 'POST',
440 headers: { 'Content-Type': 'application/json' },
441 body: JSON.stringify({ email: currentEmail })
442 });
443
444 const data = await response.json();
445
446 if (data.success) {
447 alert('New verification code sent!');
448 startCountdown(30);
449 if (data.developmentCode) {
450 console.log('🔐 New development code:', data.developmentCode);
451 verificationCode.value = data.developmentCode;
452 }
453 } else {
454 alert(data.message || 'Failed to resend code');
455 }
456 } catch (error) {
457 console.error('Resend error:', error);
458 alert('An error occurred');
459 }
460 });
461
462 changeEmailLink.addEventListener('click', (e) => {
463 e.preventDefault();
464 modal.style.display = 'none';
465 clearInterval(countdownInterval);
466 // Scroll to email field
467 document.getElementById('owner-email').focus();
468 });
469
470 // Close modal functionality
471 closeBtns.forEach(btn => {
472 btn.addEventListener('click', () => {
473 modal.style.display = 'none';
474 successModal.style.display = 'none';
475 clearInterval(countdownInterval);
476 });
477 });
478
479 window.addEventListener('click', (event) => {
480 if (event.target === modal) {
481 modal.style.display = 'none';
482 clearInterval(countdownInterval);
483 }
484 if (event.target === successModal) {
485 successModal.style.display = 'none';
486 }
487 });
488
489 // Real-time password strength indicator
490 const passwordInput = document.getElementById('password');
491 passwordInput.addEventListener('input', () => {
492 const password = passwordInput.value;
493 const strengthIndicator = document.createElement('div');
494 strengthIndicator.className = 'password-strength';
495
496 let strength = 0;
497 if (password.length >= 8) strength++;
498 if (/[a-z]/.test(password)) strength++;
499 if (/[A-Z]/.test(password)) strength++;
500 if (/\d/.test(password)) strength++;
501 if (/[@$!%*?&]/.test(password)) strength++;
502
503 const strengthText = ['Very Weak', 'Weak', 'Fair', 'Good', 'Strong'][strength - 1] || 'Very Weak';
504 const strengthColor = ['#dc3545', '#dc3545', '#ffc107', '#28a745', '#28a745'][strength - 1] || '#dc3545';
505
506 const existingIndicator = passwordInput.parentElement.querySelector('.password-strength');
507 if (existingIndicator) existingIndicator.remove();
508
509 const indicator = document.createElement('small');
510 indicator.className = 'password-strength';
511 indicator.style.color = strengthColor;
512 indicator.textContent = `Password Strength: ${strengthText}`;
513 passwordInput.parentElement.appendChild(indicator);
514 });
515 });
516</script>
517</body>
518</html>
Note: See TracBrowser for help on using the repository browser.