mirror of
https://github.com/balzack/databag.git
synced 2025-04-23 01:55:17 +00:00
adding login screen
This commit is contained in:
parent
423859113c
commit
956d41d1f5
@ -17,6 +17,8 @@
|
||||
"dependencies": {
|
||||
"@mantine/core": "^7.11.2",
|
||||
"@mantine/hooks": "^7.11.2",
|
||||
"@tabler/core": "^1.0.0-beta20",
|
||||
"@tabler/icons-react": "^3.12.0",
|
||||
"@testing-library/jest-dom": "5.16.5",
|
||||
"@testing-library/react": "13.4.0",
|
||||
"@types/jest": "29.0.3",
|
||||
|
@ -1,3 +1,10 @@
|
||||
.app {
|
||||
background-color: var(--mantine-color-surface-1);
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.focus {
|
||||
&:focus {
|
||||
border-color: red;
|
||||
|
@ -8,6 +8,7 @@ import { createTheme, MantineProvider, virtualColor } from '@mantine/core'
|
||||
import './App.css'
|
||||
import '@mantine/core/styles.css'
|
||||
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
|
||||
import classes from './App.module.css'
|
||||
|
||||
const theme = createTheme({
|
||||
primaryColor: 'databag-green',
|
||||
@ -77,8 +78,10 @@ export function App() {
|
||||
const scheme = selectedScheme === 'light' ? 'light' : selectedScheme === 'dark' ? 'dark' : defaultScheme
|
||||
|
||||
return (
|
||||
<MantineProvider forceColorScheme={scheme} theme={theme}>
|
||||
<RouterProvider router={router} />
|
||||
</MantineProvider>
|
||||
<div className={classes.app}>
|
||||
<MantineProvider forceColorScheme={scheme} theme={theme}>
|
||||
<RouterProvider router={router} />
|
||||
</MantineProvider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
47
app/client/web/src/access/Access.module.css
Normal file
47
app/client/web/src/access/Access.module.css
Normal file
@ -0,0 +1,47 @@
|
||||
.split {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 16px;
|
||||
gap: 16px;
|
||||
|
||||
.input {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.submit {
|
||||
width: 20%;
|
||||
min-width: 92px;
|
||||
}
|
||||
|
||||
.float {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.settings {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
background-color: #90bea7;
|
||||
|
||||
.splash {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,63 @@
|
||||
import React from 'react'
|
||||
import { useAccess } from './useAccess.hook'
|
||||
import classes from './Access.module.css';
|
||||
import { Select, Space, Title, Image, Button, PasswordInput, TextInput } from '@mantine/core';
|
||||
import login from '../images/login.png';
|
||||
import { IconLock, IconUser, IconSettings } from '@tabler/icons-react'
|
||||
|
||||
export function Access() {
|
||||
|
||||
const { state, actions } = useAccess()
|
||||
|
||||
const change = (ev) => {
|
||||
console.log(ev);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<span>Access</span>
|
||||
<div className={classes.split}>
|
||||
{ (state.display === 'medium' || state.display === 'large') && (
|
||||
<div className={classes.left}>
|
||||
<Image className={classes.splash} src={login} fit="contain" />
|
||||
</div>
|
||||
)}
|
||||
{ state.display != null && (
|
||||
<div className={classes.right}>
|
||||
{ state.mode !== 'admin' && (
|
||||
<Button variant="transparent" className={classes.float} leftSection={<IconSettings size={28} />} onClick={() => actions.setMode('admin')} />
|
||||
)}
|
||||
{ state.mode === 'admin' && (
|
||||
<Button variant="transparent" className={classes.float} leftSection={<IconUser size={28} />} onClick={() => actions.setMode('login')} />
|
||||
)}
|
||||
<Title order={1}>Databag</Title>
|
||||
<Title order={3}>{ state.strings.login }</Title>
|
||||
<Space h="md" />
|
||||
<TextInput className={classes.input} size="md" leftSectionPointerEvents="none" leftSection={<IconUser />} placeholder={ state.strings.username }
|
||||
onChange={(event) => actions.setUsername(event.currentTarget.value)} />
|
||||
<PasswordInput className={classes.input} size="md" leftSection={<IconLock />} placeholder={ state.strings.password }
|
||||
onChange={(event) => actions.setPassword(event.currentTarget.value)} />
|
||||
<Space h="md" />
|
||||
<Button variant="filled" className={classes.submit}>{ state.strings.login }</Button>
|
||||
<Button variant="subtle">{ state.strings.createAccount }</Button>
|
||||
<Space h="md" />
|
||||
<div className={classes.settings}>
|
||||
|
||||
<Select
|
||||
label={ state.strings.theme }
|
||||
data={ state.themes }
|
||||
value={state.theme}
|
||||
onChange={(theme) => actions.setTheme(theme)}
|
||||
/>
|
||||
|
||||
<Select
|
||||
label={ state.strings.language }
|
||||
data={ state.languages }
|
||||
value={state.language}
|
||||
onChange={(language) => actions.setLanguage(language)}
|
||||
/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
48
app/client/web/src/access/useAccess.hook.ts
Normal file
48
app/client/web/src/access/useAccess.hook.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { useState, useContext, useEffect } from 'react'
|
||||
import { SettingsContext } from '../context/SettingsContext';
|
||||
import { ContextType } from '../context/ContextType'
|
||||
|
||||
export function useAccess() {
|
||||
const settings = useContext(SettingsContext) as ContextType
|
||||
const [ state, setState ] = useState({
|
||||
display: null,
|
||||
strings: {},
|
||||
mode: 'login',
|
||||
username: '',
|
||||
password: '',
|
||||
theme: '',
|
||||
language: '',
|
||||
themes: {},
|
||||
languages: {},
|
||||
})
|
||||
|
||||
const updateState = (value: any) => {
|
||||
setState((s) => ({ ...s, ...value }))
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const { display, strings, themes, theme, languages, language } = settings.state;
|
||||
updateState({ display, strings, themes: [ ...themes ], theme, languages, language });
|
||||
}, [settings.state]);
|
||||
|
||||
const actions = {
|
||||
setMode: (mode: string) => {
|
||||
updateState({ mode });
|
||||
},
|
||||
setUsername: (username: string) => {
|
||||
updateState({ username });
|
||||
},
|
||||
setPassword: (password: string) => {
|
||||
updateState({ password });
|
||||
},
|
||||
setLanguage: (code: string) => {
|
||||
settings.actions.setLanguage(code);
|
||||
},
|
||||
setTheme: (theme: string) => {
|
||||
settings.actions.setTheme(theme);
|
||||
},
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ export function useAppContext() {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
init()
|
||||
//init()
|
||||
}, [])
|
||||
|
||||
const init = async () => {
|
||||
|
BIN
app/client/web/src/images/login.png
Normal file
BIN
app/client/web/src/images/login.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
@ -1132,6 +1132,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@popperjs/core@npm:^2.11.2":
|
||||
version: 2.11.8
|
||||
resolution: "@popperjs/core@npm:2.11.8"
|
||||
checksum: e5c69fdebf52a4012f6a1f14817ca8e9599cb1be73dd1387e1785e2ed5e5f0862ff817f420a87c7fc532add1f88a12e25aeb010ffcbdc98eace3d55ce2139cf0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@remix-run/router@npm:1.19.0":
|
||||
version: 1.19.0
|
||||
resolution: "@remix-run/router@npm:1.19.0"
|
||||
@ -1429,6 +1436,82 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tabler/core@npm:^1.0.0-beta20":
|
||||
version: 1.0.0-beta9
|
||||
resolution: "@tabler/core@npm:1.0.0-beta9"
|
||||
dependencies:
|
||||
"@popperjs/core": ^2.11.2
|
||||
"@tabler/icons": ^1.53.0
|
||||
bootstrap: 5.1.3
|
||||
peerDependencies:
|
||||
apexcharts: ^3.33.1
|
||||
autosize: ^5.0.1
|
||||
choices.js: ^10.1.0
|
||||
countup.js: ^2.0.8
|
||||
flatpickr: ^4.6.9
|
||||
imask: ^6.4.2
|
||||
jsvectormap: ^1.4.4
|
||||
litepicker: ^2.0.12
|
||||
nouislider: ^15.5.1
|
||||
tom-select: ^2.0.0
|
||||
peerDependenciesMeta:
|
||||
apexcharts:
|
||||
optional: true
|
||||
autosize:
|
||||
optional: true
|
||||
choices.js:
|
||||
optional: true
|
||||
countup.js:
|
||||
optional: true
|
||||
flatpickr:
|
||||
optional: true
|
||||
imask:
|
||||
optional: true
|
||||
jsvectormap:
|
||||
optional: true
|
||||
litepicker:
|
||||
optional: true
|
||||
nouislider:
|
||||
optional: true
|
||||
tom-select:
|
||||
optional: true
|
||||
checksum: 1cb0c3ec379e3e239d9079613e1f98aa2d34a23a175e6396e2c1b21e28398488dc28a827502c741171d75b91554192f07931529bb7bb1ebb616826c113fd63c6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tabler/icons-react@npm:^3.12.0":
|
||||
version: 3.12.0
|
||||
resolution: "@tabler/icons-react@npm:3.12.0"
|
||||
dependencies:
|
||||
"@tabler/icons": 3.12.0
|
||||
peerDependencies:
|
||||
react: ">= 16"
|
||||
checksum: 476ce8b21907aef3b979054a95b5716ea2dc1c7e177ae3621a9a373657a125d1c8621b646dfdf0f646410968b3193679f071df3a0c5ee95666e44ec5139c43da
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tabler/icons@npm:3.12.0":
|
||||
version: 3.12.0
|
||||
resolution: "@tabler/icons@npm:3.12.0"
|
||||
checksum: 763371508b92acad03ee84fbeb2c5edcb5d783c36f7f43c3d3725213da2c627100f485f6e402747fb62953934c99e18b97d5198985c3017a3519868160c51913
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tabler/icons@npm:^1.53.0":
|
||||
version: 1.119.0
|
||||
resolution: "@tabler/icons@npm:1.119.0"
|
||||
peerDependencies:
|
||||
react: ^16.x || 17.x || 18.x
|
||||
react-dom: ^16.x || 17.x || 18.x
|
||||
peerDependenciesMeta:
|
||||
react:
|
||||
optional: true
|
||||
react-dom:
|
||||
optional: true
|
||||
checksum: ef1ac50c1a47b2205cb86ca43c28d69c7b8f547ad9c2c5545190fc4a455e9767f49cb511a6f9e8dc45b046ee7d2dab3d2c87af4fd5bbb1694832a15698158753
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@testing-library/dom@npm:^8.5.0":
|
||||
version: 8.20.1
|
||||
resolution: "@testing-library/dom@npm:8.20.1"
|
||||
@ -2240,6 +2323,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bootstrap@npm:5.1.3":
|
||||
version: 5.1.3
|
||||
resolution: "bootstrap@npm:5.1.3"
|
||||
peerDependencies:
|
||||
"@popperjs/core": ^2.10.2
|
||||
checksum: 301b5ed872efba061104cf22ac93568e3837867fb5527ab9326a51510fb752bd4883e1d488225c8be72f86d9d3a55ef5b166aa7fa62c2fdd077c3f05b65752f8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"brace-expansion@npm:^1.1.7":
|
||||
version: 1.1.11
|
||||
resolution: "brace-expansion@npm:1.1.11"
|
||||
@ -2646,6 +2738,8 @@ __metadata:
|
||||
"@eslint/js": ^9.8.0
|
||||
"@mantine/core": ^7.11.2
|
||||
"@mantine/hooks": ^7.11.2
|
||||
"@tabler/core": ^1.0.0-beta20
|
||||
"@tabler/icons-react": ^3.12.0
|
||||
"@testing-library/jest-dom": 5.16.5
|
||||
"@testing-library/react": 13.4.0
|
||||
"@types/jest": 29.0.3
|
||||
|
Loading…
x
Reference in New Issue
Block a user