mirror of
https://github.com/aleksilassila/reiverr.git
synced 2026-04-21 16:25:11 +02:00
feat: Logging in multiple users, user selection
This commit is contained in:
9
src/lib/components/AddElementOverlay.svelte
Normal file
9
src/lib/components/AddElementOverlay.svelte
Normal file
@@ -0,0 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { Plus } from 'radix-icons-svelte';
|
||||
</script>
|
||||
|
||||
<div class="absolute inset-0 bg-secondary-800/75 flex items-center justify-center">
|
||||
<div class="rounded-full p-2.5 bg-secondary-800/75">
|
||||
<Plus size={32} />
|
||||
</div>
|
||||
</div>
|
||||
14
src/lib/components/Dialog/AddUserDialog.svelte
Normal file
14
src/lib/components/Dialog/AddUserDialog.svelte
Normal file
@@ -0,0 +1,14 @@
|
||||
<script lang="ts">
|
||||
import Dialog from './Dialog.svelte';
|
||||
import Login from '../Login.svelte';
|
||||
import { navigate } from '../StackRouter/StackRouter.js';
|
||||
</script>
|
||||
|
||||
<Dialog let:close>
|
||||
<Login
|
||||
on:login={() => {
|
||||
close();
|
||||
navigate('/', { refresh: true });
|
||||
}}
|
||||
/>
|
||||
</Dialog>
|
||||
@@ -27,7 +27,7 @@
|
||||
$$restProps.class
|
||||
)}
|
||||
>
|
||||
<slot />
|
||||
<slot close={handleClose} />
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
64
src/lib/components/Login.svelte
Normal file
64
src/lib/components/Login.svelte
Normal file
@@ -0,0 +1,64 @@
|
||||
<script lang="ts">
|
||||
import Container from '../../Container.svelte';
|
||||
import TextField from '../components/TextField.svelte';
|
||||
import Button from '../components/Button.svelte';
|
||||
import { createLocalStorageStore } from '../stores/localstorage.store';
|
||||
import { sessions } from '../stores/session.store';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
const dispatch = createEventDispatcher<{ login: null }>();
|
||||
|
||||
const baseUrl = createLocalStorageStore('baseUrl', window.location.origin || '');
|
||||
const name = createLocalStorageStore('username', '');
|
||||
let password: string = '';
|
||||
let error: string | undefined = undefined;
|
||||
|
||||
let loading = false;
|
||||
|
||||
function handleLogin() {
|
||||
loading = true;
|
||||
|
||||
sessions
|
||||
.addSession($baseUrl, $name, password)
|
||||
.then((res) => {
|
||||
console.log('res', res);
|
||||
if (res?.request?.status === 401) {
|
||||
error = 'Invalid credentials. Please try again.';
|
||||
} else if (res?.request.status !== 200) {
|
||||
error = 'Error occurred: ' + res.request.statusText;
|
||||
} else {
|
||||
dispatch('login');
|
||||
}
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
error = err.name + ': ' + err.message;
|
||||
})
|
||||
.finally(() => {
|
||||
loading = false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<Container class="flex flex-col" focusOnMount>
|
||||
<h1 class="header2 w-full mb-2">Login to Reiverr</h1>
|
||||
<div class="header1 mb-4">
|
||||
If this is your first time logging in, a new account will be created based on your credentials.
|
||||
</div>
|
||||
|
||||
<TextField value={$baseUrl} on:change={(e) => baseUrl.set(e.detail)} class="mb-4 w-full">
|
||||
Server
|
||||
</TextField>
|
||||
|
||||
<TextField value={$name} on:change={({ detail }) => name.set(detail)} class="mb-4 w-full">
|
||||
Name
|
||||
</TextField>
|
||||
<TextField bind:value={password} type="password" class="mb-8 w-full">Password</TextField>
|
||||
|
||||
<Button type="primary-dark" disabled={loading} on:clickOrSelect={handleLogin} class="mb-4 w-full"
|
||||
>Submit</Button
|
||||
>
|
||||
|
||||
{#if error}
|
||||
<div class="text-red-300 text-center">{error}</div>
|
||||
{/if}
|
||||
</Container>
|
||||
@@ -5,6 +5,7 @@
|
||||
import classNames from 'classnames';
|
||||
import { Plus, PlusCircled } from 'radix-icons-svelte';
|
||||
import { getCardDimensions } from '../../utils';
|
||||
import AddElementOverlay from '../AddElementOverlay.svelte';
|
||||
|
||||
export let backdropUrl: string;
|
||||
|
||||
@@ -31,10 +32,6 @@
|
||||
class="bg-cover bg-center absolute inset-0"
|
||||
style={`background-image: url('${backdropUrl}')`}
|
||||
/>
|
||||
<div class="absolute inset-0 bg-secondary-800/75 flex items-center justify-center">
|
||||
<div class="rounded-full p-2.5 bg-secondary-800/75">
|
||||
<Plus size={32} />
|
||||
</div>
|
||||
</div>
|
||||
<AddElementOverlay />
|
||||
</Container>
|
||||
</AnimateScale>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { useTabs } from '../Tab/Tab';
|
||||
import { user } from '../../stores/user.store';
|
||||
import { sessions } from '../../stores/session.store';
|
||||
|
||||
enum Tabs {
|
||||
Users,
|
||||
@@ -121,7 +122,7 @@
|
||||
|
||||
<Container
|
||||
class="w-full h-12 cursor-pointer"
|
||||
on:clickOrSelect={selectIndex(Tabs.Users)}
|
||||
on:clickOrSelect={() => sessions.setActiveSession()}
|
||||
let:hasFocus
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -113,7 +113,14 @@ export function useStackRouter({
|
||||
};
|
||||
}
|
||||
|
||||
const navigate = (routeString: string, options: { replaceStack?: boolean } = {}) => {
|
||||
const navigate = (
|
||||
routeString: string,
|
||||
options: { replaceStack?: boolean; refresh?: boolean } = {}
|
||||
) => {
|
||||
if (options.refresh) {
|
||||
location.assign(routeString);
|
||||
return;
|
||||
}
|
||||
const page: Page = routeStringToRoute(routeString);
|
||||
const replaceStack = page.route.root || options.replaceStack || false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user