in the middle of refactor, just to keep track
This commit is contained in:
parent
ccc79e75d9
commit
03de896ccb
68
README.md
68
README.md
|
@ -36,3 +36,71 @@ npm run build
|
||||||
You can preview the production build with `npm run preview`.
|
You can preview the production build with `npm run preview`.
|
||||||
|
|
||||||
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
|
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
Right now, my signup page is set up like that:
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Sign Up</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { signup } from '$lib/api';
|
||||||
|
import Modal from '$components/Modal.svelte';
|
||||||
|
|
||||||
|
let showModal = true;
|
||||||
|
let modalMessage = 'Test message';
|
||||||
|
|
||||||
|
let email = '';
|
||||||
|
let password = '';
|
||||||
|
|
||||||
|
async function handleSignup() {
|
||||||
|
try {
|
||||||
|
const user = await signup(email, password);
|
||||||
|
alert('Signup successful');
|
||||||
|
} catch (err) {
|
||||||
|
alert('Signup failed because of : ' + err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeModal() {
|
||||||
|
showModal = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<main>
|
||||||
|
|
||||||
|
<div class="colonel">
|
||||||
|
<input type="email" bind:value={email} placeholder="Email">
|
||||||
|
<input type="password" bind:value={password} placeholder="Password">
|
||||||
|
<button class="btn-fly" on:click={handleSignup}>Sign Up</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if showModal}
|
||||||
|
<Modal {modalMessage} on:close={closeModal} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
And input is set up like that in styles/forms.scss:
|
||||||
|
|
||||||
|
input[type=text], input[type=password], input[type=email], input[type=number], input[type=date], select {
|
||||||
|
padding: 12px 0px;
|
||||||
|
margin: 8px 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 5px solid $fg-color;
|
||||||
|
background-color: $bg-color;
|
||||||
|
color: $fg-color;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 400;
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
border-bottom: 5px solid $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
So the email field has a red border on bottom when focused.
|
||||||
|
|
||||||
|
I would like that borer to become green when the email is valid.
|
|
@ -8,8 +8,10 @@
|
||||||
"name": "brz9front",
|
"name": "brz9front",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"cookie": "^0.5.0",
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"normalize.css": "^8.0.1"
|
"normalize.css": "^8.0.1",
|
||||||
|
"svelte-navigator": "^3.2.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-auto": "^2.0.0",
|
"@sveltejs/adapter-auto": "^2.0.0",
|
||||||
|
@ -1012,7 +1014,6 @@
|
||||||
"version": "0.5.0",
|
"version": "0.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
|
||||||
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
|
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
|
@ -1048,6 +1049,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dedent-js": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ=="
|
||||||
|
},
|
||||||
"node_modules/deep-is": {
|
"node_modules/deep-is": {
|
||||||
"version": "0.1.4",
|
"version": "0.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||||
|
@ -1782,6 +1788,14 @@
|
||||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/lower-case": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
"version": "0.30.0",
|
"version": "0.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz",
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz",
|
||||||
|
@ -1866,6 +1880,15 @@
|
||||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
|
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/no-case": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
|
||||||
|
"dependencies": {
|
||||||
|
"lower-case": "^2.0.2",
|
||||||
|
"tslib": "^2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/normalize-path": {
|
"node_modules/normalize-path": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
|
@ -1948,6 +1971,15 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pascal-case": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
|
||||||
|
"dependencies": {
|
||||||
|
"no-case": "^3.0.4",
|
||||||
|
"tslib": "^2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path-exists": {
|
"node_modules/path-exists": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||||
|
@ -2377,7 +2409,6 @@
|
||||||
"version": "3.59.1",
|
"version": "3.59.1",
|
||||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.1.tgz",
|
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.1.tgz",
|
||||||
"integrity": "sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==",
|
"integrity": "sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
|
@ -2419,6 +2450,31 @@
|
||||||
"svelte": ">=3.19.0"
|
"svelte": ">=3.19.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/svelte-navigator": {
|
||||||
|
"version": "3.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/svelte-navigator/-/svelte-navigator-3.2.2.tgz",
|
||||||
|
"integrity": "sha512-Xio4ohLUG1nQJ+ENNbLphXXu9L189fnI1WGg+2Q3CIMPe8Jm2ipytKQthdBs8t0mN7p3Eb03SE9hq0xZAqwQNQ==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"dependencies": {
|
||||||
|
"svelte2tsx": "^0.1.151"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"svelte": "3.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/svelte2tsx": {
|
||||||
|
"version": "0.1.193",
|
||||||
|
"resolved": "https://registry.npmjs.org/svelte2tsx/-/svelte2tsx-0.1.193.tgz",
|
||||||
|
"integrity": "sha512-vzy4YQNYDnoqp2iZPnJy7kpPAY6y121L0HKrSBjU/IWW7DQ6T7RMJed2VVHFmVYm0zAGYMDl9urPc6R4DDUyhg==",
|
||||||
|
"dependencies": {
|
||||||
|
"dedent-js": "^1.0.1",
|
||||||
|
"pascal-case": "^3.1.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"svelte": "^3.24",
|
||||||
|
"typescript": "^4.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/text-table": {
|
"node_modules/text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||||
|
@ -2456,6 +2512,11 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tslib": {
|
||||||
|
"version": "2.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz",
|
||||||
|
"integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA=="
|
||||||
|
},
|
||||||
"node_modules/type-check": {
|
"node_modules/type-check": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||||
|
@ -2480,6 +2541,19 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "4.9.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
||||||
|
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||||
|
"peer": true,
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "5.22.1",
|
"version": "5.22.1",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.22.1.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-5.22.1.tgz",
|
||||||
|
|
|
@ -24,7 +24,9 @@
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"cookie": "^0.5.0",
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"normalize.css": "^8.0.1"
|
"normalize.css": "^8.0.1",
|
||||||
|
"svelte-navigator": "^3.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<!-- Footer.svelte -->
|
||||||
|
|
||||||
|
<footer class="page-footer">
|
||||||
|
<p>Copyright © 2023 My Website</p>
|
||||||
|
</footer>
|
|
@ -0,0 +1,59 @@
|
||||||
|
<!-- Header.svelte -->
|
||||||
|
<script>
|
||||||
|
export let isLoggedIn = false;
|
||||||
|
export let showUserNav = true;
|
||||||
|
export let showHome = true;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<nav>
|
||||||
|
<div class="nav-left">
|
||||||
|
{#if showHome}
|
||||||
|
<a href="/">
|
||||||
|
<span class="brz9-icon-home"></span>
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
<span></span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="nav-right">
|
||||||
|
{#if showUserNav}
|
||||||
|
{#if isLoggedIn}
|
||||||
|
<a href="/profile">
|
||||||
|
<span class="brz9-icon-user"></span>
|
||||||
|
</a>
|
||||||
|
<a href="/logout">
|
||||||
|
<span class="brz9-icon-exit"></span>
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
<a href="/login">
|
||||||
|
<span class="brz9-icon-enter"></span>
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
|
||||||
|
{:else}
|
||||||
|
<span></span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
header nav {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 1em;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
.nav-left, .nav-right {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
margin-right: 1em;
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -16,6 +16,7 @@
|
||||||
</header>
|
</header>
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<p>{modalMessage}</p>
|
<p>{modalMessage}</p>
|
||||||
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.modal-content {
|
.modal-content {
|
||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
|
padding: 30px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
button {
|
button {
|
||||||
|
|
|
@ -26,6 +26,7 @@ export async function login(email, password) {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
|
credentials: 'include',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
email: email,
|
email: email,
|
||||||
password: password
|
password: password
|
||||||
|
@ -38,6 +39,9 @@ export async function login(email, password) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here you could do something with the login response, like storing a user token
|
// Here you could do something with the login response, like storing a user token
|
||||||
|
//localStorage.setItem('userToken', data.token);
|
||||||
|
//cookie.set('userToken', data.token, { expires: 7 });
|
||||||
|
//cookie.set("check", "check", { expires: 7 })
|
||||||
|
console.log(data)
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Header from '$components/Header.svelte';
|
||||||
let text = '';
|
let text = '';
|
||||||
const apiUrl = import.meta.env.VITE_API_URL;
|
const apiUrl = import.meta.env.VITE_API_URL;
|
||||||
|
|
||||||
|
@ -38,8 +39,9 @@
|
||||||
}
|
}
|
||||||
// Fetch notes when the component is first rendered
|
// Fetch notes when the component is first rendered
|
||||||
fetchNotes();
|
fetchNotes();
|
||||||
|
export let showHome = false;
|
||||||
</script>
|
</script>
|
||||||
|
<Header {showHome}/>
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
<h1>Welcome to SvelteKit</h1>
|
<h1>Welcome to SvelteKit</h1>
|
||||||
|
@ -53,7 +55,7 @@
|
||||||
<input bind:value={text} type="text" placeholder="Enter note text" />
|
<input bind:value={text} type="text" placeholder="Enter note text" />
|
||||||
<button on:click={createNote}>Create Note</button>
|
<button on:click={createNote}>Create Note</button>
|
||||||
<br>
|
<br>
|
||||||
<button on:click={fetchNotes}>Refresh Notes</button>
|
<button class="blob-button" on:click={fetchNotes}>Refresh Notes</button>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
{#each notes as note}
|
{#each notes as note}
|
||||||
|
@ -63,4 +65,12 @@
|
||||||
|
|
||||||
<h4>Just to check, the current API endpoint is : {apiUrl}</h4>
|
<h4>Just to check, the current API endpoint is : {apiUrl}</h4>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
ul li {
|
||||||
|
max-width: 300px;
|
||||||
|
line-break: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { redirect } from "@sveltejs/kit";
|
||||||
|
import { login } from '$lib/api';
|
||||||
|
|
||||||
|
export const load = async (event) => {
|
||||||
|
console.log("hello from backend")
|
||||||
|
const sessionID = event.cookies.get('sessionID');
|
||||||
|
|
||||||
|
if (sessionID) {
|
||||||
|
throw redirect('/profile');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
default: async (event) => {
|
||||||
|
const formData = await event.request.formData();
|
||||||
|
const email = formData.get('email');
|
||||||
|
const password = formData.get('password');
|
||||||
|
|
||||||
|
|
||||||
|
const apiUrl = import.meta.env.VITE_API_URL;
|
||||||
|
|
||||||
|
const res = await fetch(apiUrl + '/login', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
credentials: 'include',
|
||||||
|
body: JSON.stringify({
|
||||||
|
email: email,
|
||||||
|
password: password
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.ok) {
|
||||||
|
console.log("ok")
|
||||||
|
return redirect('/profile');
|
||||||
|
} else {
|
||||||
|
console.log("not ok")
|
||||||
|
const error = await res.json();
|
||||||
|
return {
|
||||||
|
status: 400,
|
||||||
|
redirect: '/login',
|
||||||
|
body: { error }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
|
@ -4,27 +4,66 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { login } from '$lib/api';
|
import { login } from '$lib/api';
|
||||||
|
import { isValidEmail } from '$lib/utils';
|
||||||
|
import Modal from '$components/Modal.svelte';
|
||||||
|
import Header from '$components/Header.svelte';
|
||||||
|
import Footer from '$components/Footer.svelte';
|
||||||
|
import { navigate } from 'svelte-navigator';
|
||||||
|
|
||||||
|
let showModal = false;
|
||||||
|
let modalMessage = 'Test message';
|
||||||
|
|
||||||
let email = '';
|
let email = '';
|
||||||
let password = '';
|
let password = '';
|
||||||
|
|
||||||
async function handleLogin() {
|
async function handleLogin() {
|
||||||
|
return;
|
||||||
|
if (!isValidEmail(email)){
|
||||||
|
modalMessage = "Please enter the email address you used to sign up.";
|
||||||
|
showModal = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const user = await login(email, password);
|
const user = await login(email, password);
|
||||||
alert('Login successful');
|
navigate('/profile');
|
||||||
|
//reload the page
|
||||||
|
location.reload();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
alert('Login failed because of : ' + err);
|
modalMessage = err;
|
||||||
|
showModal = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function closeModal() {
|
||||||
|
showModal = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let showUserNav = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<Header {showUserNav} />
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
<form class="colonel">
|
<form class="colonel" on:submit={handleLogin}>
|
||||||
<input type="email" placeholder="Email" bind:value={email} required>
|
<input type="email" placeholder="Email" bind:value={email} required>
|
||||||
<input type="password" placeholder="Password" bind:value={password} required>
|
<input type="password" placeholder="P@s5word" bind:value={password} required>
|
||||||
|
|
||||||
<button class="btn-fly" on:click={handleLogin}>Log in</button>
|
<button type="submit" class="btn-fly">Log in</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</main>
|
<form class="colonel" method="POST">
|
||||||
|
<input type="email" name="email" placeholder="Email" bind:value={email} required>
|
||||||
|
<input type="password" name="password" placeholder="P@s5word" bind:value={password} required>
|
||||||
|
|
||||||
|
<button type="submit" class="btn-fly">Log in</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{#if showModal}
|
||||||
|
<Modal on:close={closeModal}>
|
||||||
|
<p>{modalMessage}</p>
|
||||||
|
</Modal>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
</main>
|
||||||
|
<Footer />
|
|
@ -0,0 +1,22 @@
|
||||||
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
//import { getUserData } from '$lib/api'; // This function should send a request to your server to get the user's data.
|
||||||
|
|
||||||
|
//let user;
|
||||||
|
|
||||||
|
//onMount(async () => {
|
||||||
|
// user = await getUserData();
|
||||||
|
//});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<h2>Profile</h2>
|
||||||
|
<!-- Path: src/routes/profile/+page.svelte
|
||||||
|
{#if user}
|
||||||
|
<h1>Welcome, {user.name}!</h1>
|
||||||
|
<p>Your email is {user.email}.</p>
|
||||||
|
|
||||||
|
{:else}
|
||||||
|
<p>Loading...</p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
-->
|
|
@ -6,34 +6,49 @@
|
||||||
import { signup } from '$lib/api';
|
import { signup } from '$lib/api';
|
||||||
import { isValidEmail, isValidPassword } from '$lib/utils';
|
import { isValidEmail, isValidPassword } from '$lib/utils';
|
||||||
import Modal from '$components/Modal.svelte';
|
import Modal from '$components/Modal.svelte';
|
||||||
|
import Header from '$components/Header.svelte';
|
||||||
|
import Footer from '$components/Footer.svelte';
|
||||||
|
import { navigate } from 'svelte-navigator';
|
||||||
|
|
||||||
let showModal = true;
|
let showModal = false;
|
||||||
let modalMessage = 'Test message';
|
let modalMessage = 'Test message';
|
||||||
|
|
||||||
let email = '';
|
let email = '';
|
||||||
let password = '';
|
let password = '';
|
||||||
|
|
||||||
async function handleSignup() {
|
async function handleSignup() {
|
||||||
|
if (!isValidEmail(email)){
|
||||||
|
modalMessage = 'This: "'+ email +'" does not look like a valid email address. Imagine you lose your password, how would you get it back? We need to send you an email. Without a valid email address, that will be difficult.';
|
||||||
|
showModal = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isValidPassword(password)){
|
||||||
|
modalMessage = 'My bad, I thought the UI was clear. Password must be at least 8 characters long with at least one number, one lowercase letter, one uppercase letter and one special character (try again until the line is no longer red, you silly goose)';
|
||||||
|
showModal = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const user = await signup(email, password);
|
const user = await signup(email, password);
|
||||||
alert('Signup successful');
|
sessionStorage.setItem('formSubmitted', 'true');
|
||||||
|
navigate('/signup/success');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
alert('Signup failed because of : ' + err);
|
modalMessage = err;
|
||||||
|
showModal = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function handleSubmit(event) {
|
|
||||||
event.preventDefault(); // prevent the form from refreshing the page
|
|
||||||
await handleSignup();
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeModal() {
|
function closeModal() {
|
||||||
showModal = false;
|
showModal = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let showUserNav = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<Header {showUserNav} />
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
<form class="colonel" on:submit={handleSubmit}>
|
<form class="colonel" on:submit={handleSignup}>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
bind:value={email}
|
bind:value={email}
|
||||||
|
@ -46,11 +61,14 @@
|
||||||
placeholder="Pas$w0rd"
|
placeholder="Pas$w0rd"
|
||||||
class:valid={isValidPassword(password)}
|
class:valid={isValidPassword(password)}
|
||||||
>
|
>
|
||||||
<button type="submit" class="btn-fly" on:click={handleSignup}>Sign Up</button>
|
<button type="submit" class="btn-fly">Sign Up</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{#if showModal}
|
{#if showModal}
|
||||||
<Modal {modalMessage} on:close={closeModal} />
|
<Modal on:close={closeModal}>
|
||||||
|
<p>{modalMessage}</p>
|
||||||
|
</Modal>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
<Footer />
|
|
@ -0,0 +1,33 @@
|
||||||
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import { navigate } from 'svelte-navigator';
|
||||||
|
import Header from '$components/Header.svelte';
|
||||||
|
import Footer from '$components/Footer.svelte';
|
||||||
|
|
||||||
|
let formSubmitted = false;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
formSubmitted = sessionStorage.getItem('formSubmitted') === 'true';
|
||||||
|
if (!formSubmitted) {
|
||||||
|
navigate('/');
|
||||||
|
//load the page again
|
||||||
|
location.reload();
|
||||||
|
} else {
|
||||||
|
// Clear the flag from session storage after checking it
|
||||||
|
//sessionStorage.removeItem('formSubmitted');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let showUserNav = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if formSubmitted}
|
||||||
|
<Header {showUserNav}/>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<h1>Signup successful!</h1>
|
||||||
|
<p>You can now check your inbox to activate your account.</p>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
{/if}
|
|
@ -0,0 +1,47 @@
|
||||||
|
@function random-range($min, $max) {
|
||||||
|
@return random() * ($max - $min) + $min + '%';
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin random-blob-shape {
|
||||||
|
$x1: random-range(40, 60);
|
||||||
|
$x2: random-range(10, 30);
|
||||||
|
$x3: random-range(50, 70);
|
||||||
|
$x4: random-range(20, 40);
|
||||||
|
$y1: random-range(30, 70);
|
||||||
|
$y2: random-range(20, 40);
|
||||||
|
$y3: random-range(60, 80);
|
||||||
|
$y4: random-range(30, 70);
|
||||||
|
|
||||||
|
$horizontalRadii: $x1 $x2 $x3 $x4;
|
||||||
|
$verticalRadii: $y1 $y2 $y3 $y4;
|
||||||
|
|
||||||
|
border-radius: #{$horizontalRadii} / #{$verticalRadii};
|
||||||
|
}
|
||||||
|
|
||||||
|
.blob-button {
|
||||||
|
background-color: #ff7f50;
|
||||||
|
color: #fff;
|
||||||
|
padding: 25px;
|
||||||
|
font-size: 16px;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
@include random-blob-shape;
|
||||||
|
/*animation: blob-animation 4s infinite ease-in-out;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@keyframes blob-animation {
|
||||||
|
0% {
|
||||||
|
border-radius: 50% 20% 60% 40% / 60% 30% 70% 40%;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
border-radius: 70% 30% 50% 20% / 40% 60% 20% 60%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
border-radius: 50% 20% 60% 40% / 60% 30% 70% 40%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
|
@ -31,4 +31,4 @@ input[type=text], input[type=password], input[type=email], input[type=number], i
|
||||||
&.valid {
|
&.valid {
|
||||||
border-bottom: 5px solid $fg-color;
|
border-bottom: 5px solid $fg-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
@ -43,4 +53,9 @@
|
||||||
*{
|
*{
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer.page-footer {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
|
@ -4,3 +4,4 @@
|
||||||
@import 'layout';
|
@import 'layout';
|
||||||
@import 'responsive';
|
@import 'responsive';
|
||||||
@import 'forms';
|
@import 'forms';
|
||||||
|
@import 'blob';
|
||||||
|
|
Loading…
Reference in New Issue