+page.svelte 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <script>
  2. import { onMount } from 'svelte';
  3. import { authentication } from '../store.js';
  4. import { goto } from '$app/navigation';
  5. import { fade } from 'svelte/transition';
  6. let isAuthenticated = false;
  7. let isLoading = true;
  8. let showPassword = false;
  9. $: authentication.subscribe((value) => {
  10. isAuthenticated = !!value;
  11. });
  12. onMount(() => {
  13. try {
  14. const storedAuth = localStorage.getItem('authentication');
  15. if (storedAuth) {
  16. authentication.set(JSON.parse(storedAuth));
  17. }
  18. } catch (error) {
  19. console.error('Error parsing stored auth:', error);
  20. } finally {
  21. isLoading = false;
  22. }
  23. });
  24. async function submit(event) {
  25. event.preventDefault();
  26. const formData = new FormData(event.target);
  27. const username = formData.get('username');
  28. const password = formData.get('password');
  29. if (!username || !password) {
  30. alert('Please enter both username and password.');
  31. return;
  32. }
  33. const data = {
  34. username: username,
  35. password: password
  36. };
  37. try {
  38. const response = await fetch(import.meta.env.VITE_AUTH_HOST + '/api/authenticate', {
  39. method: 'POST',
  40. headers: {
  41. 'Content-Type': 'application/json'
  42. },
  43. body: JSON.stringify(data)
  44. });
  45. if (response.ok) {
  46. const result = await response.json();
  47. authentication.set(result);
  48. localStorage.setItem('authentication', JSON.stringify(result));
  49. await goto('/portfolio');
  50. } else {
  51. const error = await response.json();
  52. console.error('Login failed:', error);
  53. alert('Login failed: ' + error.message);
  54. }
  55. } catch (err) {
  56. console.error('Error during login:', err);
  57. alert('An error occurred. Please try again.');
  58. }
  59. }
  60. function navigateToRegister() {
  61. window.location.href = '/register';
  62. }
  63. function togglePasswordVisibility() {
  64. showPassword = !showPassword;
  65. }
  66. </script>
  67. <svelte:head>
  68. <title>Login</title>
  69. <meta name="description" content="Login page" />
  70. </svelte:head>
  71. <div in:fade class="text-column">
  72. {#if isLoading}
  73. <p>Loading...</p>
  74. {:else if !isAuthenticated}
  75. <div class="card">
  76. <form on:submit={submit}>
  77. <input type="text" name="username" placeholder="username" class="input-field" />
  78. <div class="password-container">
  79. <input
  80. type={showPassword ? 'text' : 'password'}
  81. name="password"
  82. placeholder="password"
  83. class="input-field"
  84. />
  85. <span class="eye-icon" on:click={togglePasswordVisibility}>
  86. {#if showPassword}
  87. 👁️‍🗨️
  88. {:else}
  89. 👁️‍🗨️
  90. {/if}
  91. </span>
  92. </div>
  93. <button type="submit" class="add-button">Login</button>
  94. <button type="button" class="register-button" on:click={navigateToRegister}>Register</button>
  95. </form>
  96. </div>
  97. {/if}
  98. </div>
  99. <style>
  100. input::placeholder {
  101. opacity: 0.5;
  102. }
  103. .password-container {
  104. position: relative;
  105. }
  106. .eye-icon {
  107. position: absolute;
  108. right: 10px;
  109. top: 50%;
  110. transform: translateY(-50%);
  111. cursor: pointer;
  112. font-size: 1.1rem;
  113. color: #666;
  114. user-select: none;
  115. }
  116. .input-field {
  117. width: 100%;
  118. padding: 0.5rem 2.5rem 0.5rem 0.5rem;
  119. margin-bottom: 1rem;
  120. box-sizing: border-box;
  121. }
  122. .add-button,
  123. .register-button {
  124. padding: 0.5rem 1rem;
  125. margin-top: 0.5rem;
  126. border: none;
  127. border-radius: 4px;
  128. cursor: pointer;
  129. font-weight: bold;
  130. }
  131. .add-button {
  132. background-color: #4caf50;
  133. color: white;
  134. margin-right: 0.5rem;
  135. }
  136. .register-button {
  137. background-color: #2196f3;
  138. color: white;
  139. }
  140. </style>