chore: more work on the app
This commit is contained in:
59
webpage/src/routes/models/+page.svelte
Normal file
59
webpage/src/routes/models/+page.svelte
Normal file
@@ -0,0 +1,59 @@
|
||||
<script lang="ts">
|
||||
let list = $state<{
|
||||
name: string,
|
||||
id: string,
|
||||
}[]>([]);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>
|
||||
Models
|
||||
</title>
|
||||
</svelte:head>
|
||||
|
||||
<main>
|
||||
{#if list.length > 0}
|
||||
<div class="list-header">
|
||||
<h2>My Models</h2>
|
||||
<div class="expand"></div>
|
||||
<a class="button" href="/models/add">
|
||||
New
|
||||
</a>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Name
|
||||
</th>
|
||||
<th>
|
||||
<!-- Open Button -->
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each list as item}
|
||||
<tr>
|
||||
<td>
|
||||
{item.name}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a class="button simple" href="/models/edit?id={item.id}">
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
{:else}
|
||||
<h2 class="text-center">
|
||||
You don't have any models
|
||||
</h2>
|
||||
<div class="text-center">
|
||||
<a class="button padded" href="/models/add">
|
||||
Create a new model
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
80
webpage/src/routes/models/add/+page.svelte
Normal file
80
webpage/src/routes/models/add/+page.svelte
Normal file
@@ -0,0 +1,80 @@
|
||||
<script lang="ts">
|
||||
import FileUpload from "src/lib/FileUpload.svelte";
|
||||
import MessageSimple from "src/lib/MessageSimple.svelte";
|
||||
|
||||
import "src/styles/forms.css";
|
||||
|
||||
let submitted = $state(false);
|
||||
|
||||
let message: MessageSimple;
|
||||
|
||||
let buttonClicked: Promise<void> = $state(Promise.resolve());
|
||||
|
||||
let data = $state<{
|
||||
name: string,
|
||||
file?: File,
|
||||
}>({
|
||||
name: '',
|
||||
file: undefined,
|
||||
});
|
||||
|
||||
function onSubmit() {
|
||||
message.display("");
|
||||
buttonClicked = new Promise<void>(() => {});
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Create new Model</title>
|
||||
</svelte:head>
|
||||
|
||||
<main>
|
||||
<h1>
|
||||
Create new Model
|
||||
</h1>
|
||||
<form class:submitted on:submit|preventDefault={onSubmit}>
|
||||
<fieldset>
|
||||
<label for="name">Name</label>
|
||||
<input id="name" name="name" required bind:value={data.name} />
|
||||
<!--{{if .NameFoundError}}
|
||||
<span class="form-msg error">
|
||||
You already have a model with that name.
|
||||
</span>
|
||||
{{end}}-->
|
||||
</fieldset>
|
||||
<fieldset class="file-upload" >
|
||||
<label for="file">Base image</label>
|
||||
<div class="form-msg">
|
||||
Please provide a base image.<br/>
|
||||
This image is a sample of the images that you are going to classfiy.
|
||||
</div>
|
||||
<FileUpload replace_slot bind:file={data.file} >
|
||||
<img src="/imgs/upload-icon.png" alt="" />
|
||||
<span>
|
||||
Upload image
|
||||
</span>
|
||||
<div slot="replaced-name">
|
||||
<span>
|
||||
Image selected
|
||||
</span>
|
||||
</div>
|
||||
</FileUpload>
|
||||
</fieldset>
|
||||
<MessageSimple bind:this={message} />
|
||||
{#await buttonClicked}
|
||||
<div class="text-center">
|
||||
File Uploading
|
||||
</div>
|
||||
{:then}
|
||||
<button>
|
||||
Create
|
||||
</button>
|
||||
{/await}
|
||||
</form>
|
||||
</main>
|
||||
|
||||
<style lang="scss">
|
||||
main {
|
||||
padding: 20px 15vw;
|
||||
}
|
||||
</style>
|
||||
129
webpage/src/routes/user/info/+page.svelte
Normal file
129
webpage/src/routes/user/info/+page.svelte
Normal file
@@ -0,0 +1,129 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { userStore } from 'src/routes/UserStore.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import 'src/styles/forms.css';
|
||||
import { post } from 'src/lib/requests.svelte';
|
||||
import MessageSimple, { type DisplayFn } from 'src/lib/MessageSimple.svelte';
|
||||
|
||||
onMount(() => {
|
||||
if (!userStore.isLogin()) {
|
||||
goto('/login');
|
||||
}
|
||||
});
|
||||
|
||||
let email = $state(userStore.user?.email ?? '');
|
||||
|
||||
let passwordData = $state({
|
||||
old_password: '',
|
||||
password: '',
|
||||
password2: ''
|
||||
});
|
||||
|
||||
let submiitedEmail = $state(false);
|
||||
let submiitedPassword = $state(false);
|
||||
|
||||
let msgEmail: MessageSimple;
|
||||
let msgPassword: MessageSimple;
|
||||
|
||||
async function onSubmitEmail() {
|
||||
submiitedEmail = true;
|
||||
msgEmail.display('');
|
||||
|
||||
if (!userStore.user) return;
|
||||
|
||||
try {
|
||||
let req = await post('user/info', {
|
||||
id: userStore.user.id,
|
||||
email: email
|
||||
});
|
||||
userStore.user = {
|
||||
...userStore.user,
|
||||
...req
|
||||
};
|
||||
msgEmail.display('User updated successufly!', { type: 'success', timeToShow: 10000 });
|
||||
} catch (e) {
|
||||
if (e instanceof Response) {
|
||||
msgEmail.display(await e.json());
|
||||
} else {
|
||||
msgEmail.display('Could not update email');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function onSubmitPassword() {
|
||||
submiitedPassword = true;
|
||||
msgPassword.display('');
|
||||
if (!userStore.user) return;
|
||||
|
||||
try {
|
||||
await post('user/info/password', passwordData);
|
||||
passwordData = { old_password: '', password: '', password2: '' };
|
||||
msgPassword.display('Password updated successufly!', { type: 'success', timeToShow: 10000 });
|
||||
} catch (e) {
|
||||
if (e instanceof Response) {
|
||||
msgPassword.display(await e.json());
|
||||
} else {
|
||||
msgPassword.display('Could not update password');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>User Info</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="login-page">
|
||||
<div>
|
||||
<h1>User Infomation</h1>
|
||||
<form on:submit|preventDefault={onSubmitEmail} class:submiitedEmail>
|
||||
<fieldset>
|
||||
<label for="email">Email</label>
|
||||
<input type="email" required name="email" bind:value={email} />
|
||||
</fieldset>
|
||||
<MessageSimple bind:this={msgEmail} />
|
||||
<button> Update </button>
|
||||
</form>
|
||||
<form on:submit|preventDefault={onSubmitPassword} class:submiitedPassword>
|
||||
<fieldset>
|
||||
<label for="old_password">Old Password</label>
|
||||
<input
|
||||
required
|
||||
bind:value={passwordData.old_password}
|
||||
name="old_password"
|
||||
type="password"
|
||||
/>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label for="password">New Password</label>
|
||||
<input required bind:value={passwordData.password} name="password" type="password" />
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label for="password2">Repeat New Password</label>
|
||||
<input required bind:value={passwordData.password2} name="password2" type="password" />
|
||||
</fieldset>
|
||||
<MessageSimple bind:this={msgPassword} />
|
||||
<div>
|
||||
<button> Update </button>
|
||||
</div>
|
||||
</form>
|
||||
<!-- TODO Delete -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
/* Login Page */
|
||||
.login-page {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
margin-bottom: 40px;
|
||||
& > div {
|
||||
width: 40vw;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user