feat(login page): remove old page / add new

remove old components like redux / react / etc; add new / first component LoginPage
feat/x_gpu/new_version
TBS093A 2024-04-09 18:19:47 +02:00
parent a21957003a
commit 81fbd07b12
28 changed files with 25421 additions and 13702 deletions

37398
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,22 +8,18 @@
"gatsby"
],
"scripts": {
"develop": "gatsby develop",
"start": "gatsby develop",
"develop": "gatsby develop --host=0.0.0.0",
"start": "gatsby develop --host=0.0.0.0",
"build": "gatsby build",
"serve": "gatsby serve",
"clean": "gatsby clean"
},
"dependencies": {
"@reduxjs/toolkit": "^1.5.0",
"gatsby": "^2.32.3",
"gatsby-plugin-sass": "^3.2.0",
"loadash": "^1.0.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"gatsby": "^5.13.3",
"gatsby-plugin-sass": "^6.13.1",
"react": "^18",
"react-dom": "^18",
"react-particles-js": "^3.4.1",
"react-redux": "^7.2.2",
"redux": "^4.0.5",
"sass": "^1.32.7"
}
}

View File

@ -1,94 +0,0 @@
import React from 'react'
import Particles from 'react-particles-js'
const CanvasBackgroundAnimation = () => {
let particleColor = '#008000'
let darkGreen = '#005e00'
let menuColor = '#161c1d'
let params = {
particles: {
number: { value: 120, density: { enable: true, value_area: 800 } },
color: { value: particleColor },
shape: {
type: "circle",
stroke: { width: 0, color: darkGreen },
polygon: { nb_sides: 5 }
},
opacity: {
value: 1,
random: false,
anim: { enable: false, speed: 1, opacity_min: 0.1, sync: false }
},
size: {
value: 3,
random: true,
anim: { enable: false, speed: 40, size_min: 0.1, sync: false }
},
line_linked: {
enable: true,
distance: 150,
color: darkGreen,
opacity: 0.4,
width: 1
},
move: {
enable: true,
speed: 6,
direction: "none",
random: false,
straight: false,
out_mode: "out",
bounce: false,
attract: { enable: false, rotateX: 600, rotateY: 1200 }
}
},
interactivity: {
detect_on: "canvas",
events: {
onhover: { enable: true, mode: "repulse" },
onclick: { enable: true, mode: "push" },
resize: true
},
},
modes: {
grab: {
distance: 400,
line_linked: {
opacity: 1
}
},
bubble: {
distance: 400,
size: 40,
duration: 2,
opacity: 8,
speed: 3
},
repulse: {
distance: 200,
duration: 0.4
},
push: { particles_nb: 4 },
remove: { particles_nb: 2 }
}
}
return (
<Particles
params={ params }
style={
{
width: '100%',
height: '100%',
zIndex: '-100',
}
}
/>
)
}
export default CanvasBackgroundAnimation

View File

@ -1,43 +0,0 @@
import React, { useState, useEffect } from 'react'
import ModelShowAndDownloadForm from '../../../components/forms/model_crud/modelShowModelsAndDownload'
import ModelUpload from '../../../components/forms/model_crud/modelUpload'
const __handleSwap = (name, movement) => {
let display = {
display: 'block'
}
let hide = {
display: 'none'
}
if ( Object.keys(movement['movement']).includes(name) ) {
if (movement['movement'][name])
return display
else
return hide
} else {
return hide
}
}
const ModelCrudIndex = ( movement ) => {
return (
<div>
<div style={ __handleSwap( 'show_models_and_download', movement ) }>
<ModelShowAndDownloadForm />
</div>
<div style={ __handleSwap( 'upload_model', movement ) }>
<ModelUpload />
</div>
</div>
)
}
export default ModelCrudIndex

View File

@ -1,262 +0,0 @@
import React, { useState, useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { userAuthSelector } from '../../redux/slices/userAuthSlice'
import { userCrudSelector } from '../../redux/slices/userCrudSlice'
import userCrudAsyncThunk from '../../redux/asyncThunks/userCrudAsyncThunk'
import userAuthAsyncThunk from '../../redux/asyncThunks/userAuthAsyncThunk'
const __setShowGeneral = ( view, key, movements ) => {
let user_default = {
update_user: false,
delete_user: false
}
let model_default = {
show_models_and_dwonload: false,
upload_model: false
}
let render_default = {
show_ready_renders_and_download: false,
render_functionality: {
render_single_image: false,
render_single_set: false,
render_all: false,
render_image_by_vector: false,
render_set_by_vector: false
}
}
if (view === 'user_view') {
let new_move = user_default
new_move[key] = true
movements.user_view.setUserCrudView(
new_move
)
movements.model_view.setModelCrudView(
model_default
)
movements.render_view.setRenderView(
render_default
)
} else if (view === 'model_view') {
let new_move = model_default
new_move[key] = true
movements.model_view.setModelCrudView(
new_move
)
movements.user_view.setUserCrudView(
user_default
)
movements.render_view.setRenderView(
render_default
)
} else if (view === 'render_view') {
let new_move = render_default
if ( key in new_move ) {
new_move[key] = true
movements.render_view.setRenderView(
new_move
)
} else {
new_move['render_functionality'][key] = true
movements.render_view.setRenderView(
new_move
)
}
movements.model_view.setModelCrudView(
model_default
)
movements.user_view.setUserCrudView(
user_default
)
}
}
const __styleChanger = ( bool ) => {
let display = {
display: 'block'
}
let hide = {
display: 'none'
}
return bool ? display : hide
}
const NavigationBar = ({ movements }) => {
const { user_get } = useSelector(userCrudSelector)
const { token, user } = useSelector(userAuthSelector)
const dispatch = useDispatch()
useEffect( () => {
if ( Object.keys(user_get).length === 0 && token !== '' && user.id > 0)
dispatch(
userCrudAsyncThunk.fetchGetOneUser(
{
user_id: user.id,
token: token
}
)
)
})
const [showAccount, setShowAccount] = useState(false)
const [showModels, setShowModels] = useState(false)
const [showRender, setShowRender] = useState(false)
const [showRenderFunc, setShowRenderFunc] = useState(false)
const [clickHide, setClickHide] = useState(true)
const logout = async () => {
dispatch(
userAuthAsyncThunk.fetchLogout(
token
)
)
}
return(
<div
className="navigation_bar"
style={ clickHide ? { marginRight: '-350px' } : { marginRight: '0px' } }
>
<div
onClick={ () => setClickHide( !clickHide ) }
className="nav_bar_clickable"
>
</div>
<div className="nav_bar_general">
Menu
<div>
<div
onClick={ () => setShowAccount( !showAccount ) }
className='nav_bar_header'
>
<pre> </pre> <p> Account Settings </p>
</div>
<div style={ __styleChanger( showAccount) }>
<div>
<div className='nav_bar_option'>
<pre> </pre> <p> User info </p>
</div>
<div>
<div className='nav_bar_option'>
<pre> </pre> <p>Username: { user_get.username } </p>
</div>
<div className='nav_bar_option'>
<pre> </pre> <p> E-mail: { user_get.email } </p>
</div>
</div>
</div>
<div
onClick={ () => __setShowGeneral( 'user_view', 'update_user', movements ) }
className='nav_bar_option'
>
<pre> </pre> <p> Update User </p>
</div>
<div
onClick={ () => __setShowGeneral( 'user_view', 'delete_user', movements ) }
className='nav_bar_option'
>
<pre> </pre> <p> Delete User </p>
</div>
</div>
</div>
<div>
<div
onClick={ () => setShowModels( !showModels ) }
className='nav_bar_header'
>
<pre> </pre><p>Models</p>
</div>
<div style={ __styleChanger( showModels ) } className='nav_bar_option'>
<div
onClick={ () => __setShowGeneral( 'model_view', 'show_models_and_download', movements )}
className='nav_bar_option'
>
<pre> </pre> <p> Show Models & Download</p>
</div>
<div
onClick={ () => __setShowGeneral( 'model_view', 'upload_model', movements ) }
className='nav_bar_option'
>
<pre> </pre> <p> Upload Model</p>
</div>
</div>
</div>
<div>
<div
onClick={ () => setShowRender( !showRender ) }
className='nav_bar_header'
>
<pre> </pre> <p> Render </p>
</div>
<div style={ __styleChanger( showRender ) }>
<div>
<div
onClick={ () => setShowRenderFunc( !showRenderFunc ) }
className='nav_bar_option'
>
<pre> </pre> <p> Render Functionality </p>
</div>
<div style={ __styleChanger( showRenderFunc ) }>
<div
onClick={ () => __setShowGeneral( 'render_view', 'render_single_image', movements ) }
className='nav_bar_option'
>
<pre> </pre> <p> Render Single Image </p>
</div>
<div
onClick={ () => __setShowGeneral( 'render_view', 'render_single_set', movements ) }
className='nav_bar_option'
>
<pre> </pre> <p> Render Single Set</p>
</div>
<div
onClick={ () => __setShowGeneral( 'render_view', 'render_all', movements ) }
className='nav_bar_option'
>
<pre> </pre> <p> Render All Sets</p>
</div>
<div
onClick={ () => __setShowGeneral( 'render_view', 'render_image_by_vector', movements ) }
className='nav_bar_option'
>
<pre> </pre> <p> Render Image By Vector</p>
</div>
<div
onClick={ () => __setShowGeneral( 'render_view', 'render_set_by_vector', movements ) }
className='nav_bar_option'
>
<pre> </pre> <p> Render Set By Vector</p>
</div>
</div>
</div>
<div
onClick={ () => __setShowGeneral( 'render_view', 'show_ready_renders_and_download', movements ) }
className='nav_bar_option'
>
<pre> </pre> <p> Show Ready Renders & Download </p>
</div>
</div>
</div>
<div onClick={ () => logout() } className='nav_bar_header'>
<pre> </pre><p> Sign Out</p>
</div>
</div>
</div>
)
}
export default NavigationBar

View File

@ -1,67 +0,0 @@
import React, { useState, useEffect } from 'react'
import RenderShowAndDownloadForm from '../../../components/forms/render_crud/renderShowReadyRendersAndDownload'
import RenderSingleImageForm from '../../../components/forms/render_websocket/renderSingleImage'
import RenderSingleSetForm from '../../../components/forms/render_websocket/renderSingleSet'
import RenderAllForm from '../../../components/forms/render_websocket/renderAll'
import RenderVectorSingleImageForm from '../../../components/forms/render_websocket/renderVectorImage'
import RenderVectorSingleSetForm from '../../../components/forms/render_websocket/renderVectorSet'
const __handleSwap = (name, movement) => {
let display = {
display: 'block'
}
let hide = {
display: 'none'
}
console.log(movement)
if ( Object.keys(movement['movement']).includes(name) ) {
if (movement['movement'][name])
return display
else
return hide
} else if (Object.keys(movement['movement']['render_functionality']).includes(name)) {
if (movement['movement']['render_functionality'][name])
return display
else
return hide
} else {
return hide
}
}
const RenderIndex = ( movement ) => {
return (
<div>
<div style={ __handleSwap( 'show_ready_renders_and_download', movement ) }>
<RenderShowAndDownloadForm />
</div>
<div style={ __handleSwap( 'render_single_image', movement ) }>
<RenderSingleImageForm />
</div>
<div style={ __handleSwap( 'render_single_set', movement ) }>
<RenderSingleSetForm />
</div>
<div style={ __handleSwap( 'render_all', movement ) }>
<RenderAllForm />
</div>
<div style={ __handleSwap( 'render_image_by_vector', movement ) }>
<RenderVectorSingleImageForm />
</div>
<div style={ __handleSwap( 'render_set_by_vector', movement ) }>
<RenderVectorSingleSetForm />
</div>
</div>
)
}
export default RenderIndex

View File

@ -1,11 +0,0 @@
import React, { useState, useEffect } from 'react'
const RenderWebsocketIndex = () => {
return (
<div>
</div>
)
}
export default RenderWebsocketIndex

View File

@ -1,14 +0,0 @@
import React, { useState, useEffect } from 'react'
import VerifyUserSession from './rootUtils'
const Root = () => {
return (
<div>
<VerifyUserSession />
</div>
)
}
export default Root

View File

@ -1,104 +0,0 @@
import React, { useState, useEffect } from 'react'
import { useSelector } from 'react-redux'
import { userAuthSelector } from '../../redux/slices/userAuthSlice'
import UserAuthIndex from './user_auth/userAuthIndex'
import UserCrudIndex from './user_crud/userCrudIndex'
import ModelCrudIndex from './model_crud/modelCrudIndex'
import RenderIndex from './render/renderIndex'
import NavigationBar from './navigationBar'
import CanvasBackgroundAnimation from './canvasBackgroundAnimation'
const GeneralView = () => {
const [userCrudView, setUserCrudView] = useState(
{
update_user: false,
delete_user: false
}
)
const [modelCrudView, setModelCrudView] = useState(
{
show_models_and_download: false,
upload_model: false
}
)
const [renderCrudView, setRenderCrudView] = useState(
{
show_ready_renders_and_download: false,
render_functionality: {
render_single_image: false,
render_single_set: false,
render_all: false,
render_image_by_vector: false,
render_set_by_vector: false
}
}
)
let movements = {
user_view: {
userCrudView: userCrudView,
setUserCrudView: setUserCrudView
},
model_view: {
modelCrudView: modelCrudView,
setModelCrudView: setModelCrudView
},
render_view: {
renderView: renderCrudView,
setRenderView: setRenderCrudView
}
}
return (
<div>
<NavigationBar
movements={ movements }
/>
<UserCrudIndex
movement={ movements.user_view.userCrudView }
/>
<ModelCrudIndex
movement={ movements.model_view.modelCrudView }
/>
<RenderIndex
movement={ movements.render_view.renderView }
/>
</div>
)
}
const VerifyUserSession = () => {
const { token, user } = useSelector(userAuthSelector)
const [showGeneral, setShowGeneral] = useState(false)
useEffect(
() => {
if ( user.id > 0 && token !== '' && showGeneral === false ) {
setShowGeneral(true)
} else if ( user.id <= 0 && token === '' && showGeneral === true ) {
setShowGeneral(false)
}
}
)
return (
<div>
{
showGeneral
? <GeneralView />
: <UserAuthIndex />
}
<CanvasBackgroundAnimation />
</div>
)
}
export default VerifyUserSession

View File

@ -1,38 +0,0 @@
import React, { useState, useEffect } from 'react'
import UserLoginForm from '../../../components/forms/user_auth/userLogin'
import UserRegisterForm from '../../../components/forms/user_auth/userRegister'
const UserAuthIndex = () => {
const [swapForm, setSwapForm] = useState(true)
const handleSwap = (event) => {
event.preventDefault()
setSwapForm(
!swapForm
)
}
return (
<div
className="float_form_auth"
style={ swapForm ? { height: '200px', marginTop: '15%' } : { height: '290px', marginTop: '13%' } }
>
{ swapForm
? <UserLoginForm />
: <UserRegisterForm />
}
<button onClick={ (event) => handleSwap(event) }>
{
swapForm
? 'Sign Up'
: 'Sign In'
}
</button>
</div>
)
}
export default UserAuthIndex

View File

@ -1,43 +0,0 @@
import React, { useState, useEffect } from 'react'
import UserUpdateForm from '../../../components/forms/user_crud/userUpdate'
import UserDeleteForm from '../../../components/forms/user_crud/userDelete'
const __handleSwap = (name, movement) => {
let display = {
display: 'block'
}
let hide = {
display: 'none'
}
if ( Object.keys(movement['movement']).includes(name) ) {
if (movement['movement'][name])
return display
else
return hide
} else {
return hide
}
}
const UserCrudIndex = ( movement ) => {
return (
<div>
<div style={ __handleSwap( 'update_user', movement ) }>
<UserUpdateForm />
</div>
<div style={ __handleSwap( 'delete_user', movement ) }>
<UserDeleteForm />
</div>
</div>
)
}
export default UserCrudIndex

View File

@ -1,26 +1,66 @@
import React from 'react';
import '../styles/general.scss'
import { Provider } from 'react-redux';
import { store } from '../redux/store';
import '../styles/general.000.scss';
import '../styles/LoginPage.cube.scss';
import Root from './func_group/root';
// import { Provider } from 'react-redux';
// import { store } from '../redux/store';
// import Root from './func_group/root';
// if you have problem with watchers - use it:
// echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
// const IndexPage = () => {
// if (typeof window !== `undefined` && store !== 0)
// return (
// <Provider store={ store }>
// <Root />
// </Provider>
// )
// else
// return (
// <>
// </>
// )
// }
const IndexPage = () => {
if (typeof window !== `undefined` && store !== 0)
return (
<Provider store={ store }>
<Root />
</Provider>
)
else
return (
<>
</>
<div className="login-container">
<header className="header">
<h1>X-GPU</h1>
</header>
<main className="main-content">
<div className="graphic-container">
<div className="cube">
<div className="front"></div>
<div className="back"></div>
<div className="right"></div>
<div className="left"></div>
<div className="top"></div>
<div className="bottom"></div>
</div>
</div>
<form className="login-form">
<div className="form-field">
<label htmlFor="login">
EMAIL
</label>
<input type="text" id="login" name="login" />
</div>
<div className="form-field">
<label htmlFor="password">
PASSWORD
</label>
<input type="password" id="password" name="password" />
</div>
<button type="submit">CONTINUE</button>
</form>
</main>
</div>
)
}
export default IndexPage
export default IndexPage

View File

@ -1,3 +0,0 @@
let API = '0.0.0.0:9090'
export const GeneralAddress = 'http://' + API
export const GeneralAddressWS = 'ws://' + API + '/render'

View File

@ -1,144 +0,0 @@
import axios from 'axios'
import { GeneralAddress } from './abstractAddress'
const APIAddress = GeneralAddress
let defaultBody = {}
const _getList = async (endpoint, token) => {
return await responseAbstract(
endpoint,
'GET',
token,
defaultBody
)
}
const _getOne = async (endpoint, objectId, token) => {
return await responseAbstract(
endpoint + objectId + '/',
'GET',
token,
defaultBody
)
}
const _post = async (endpoint, body, token) => {
return await responseAbstract(
endpoint,
'POST',
token,
body
)
}
const _patch = async (endpoint, objectId, body, token) => {
return await responseAbstract(
endpoint + objectId + '/',
'PATCH',
token,
body
)
}
const _put = async (endpoint, objectId, body, token) => {
return await responseAbstract(
endpoint + objectId + '/',
'PUT',
token,
body
)
}
const _delete = async (endpoint, objectId, token) => {
let slash = '/'
if ( objectId === '' )
slash = ''
return await responseAbstract(
endpoint + objectId + slash,
'DELETE',
token,
defaultBody
)
}
const responseAbstract = async (endpoint, method, token, body) => {
let response = await axios(
headerBuilder(
APIAddress + endpoint,
method,
token,
body,
)
)
return response
}
const headerBuilder = (url, method, token, body) => {
let headers_r = {
'authorization': token,
'x-csrftoken': getCookie('csrftoken'),
'accept': 'application/json',
'content-type': 'application/json'
}
let headers = {
url: url,
method: method,
headers: headers_r,
credentials: 'same-origin'
}
if (method === 'PUT' || method === 'POST' || method === 'PATCH') {
headers = Object.assign({}, headers, {
data: JSON.stringify(body)
})
}
return headers
}
/**
* get cookie method for CSRF verification
* @param {string} name - name of handled cookie
*/
const getCookie = (name) => {
if (!document.cookie) {
return null;
}
const token = document.cookie.split(';')
.map(c => c.trim())
.filter(c => c.startsWith(name + '='));
if (token.length === 0) {
return null;
}
return decodeURIComponent(token[0].split('=')[1]);
}
const axiosFilePost = async ( endpoint, body, token ) => {
let formData = new FormData()
formData.append('file', body.file)
formData.append('user_id', body.user_id)
let response = await axios.post(
APIAddress + endpoint,
formData,
{
headers: {
'authorization': token,
'x-csrftoken': getCookie('csrftoken')
}
}
)
console.log(response)
return response
}
export default {
APIAddress,
_getList,
_getOne,
_post,
_put,
_patch,
_delete,
axiosFilePost
}

View File

@ -1,60 +0,0 @@
import { createAsyncThunk } from '@reduxjs/toolkit'
import abstractService from './abstracts/abstractService'
let endpoint = '/model/'
const fetchGetAllModels = createAsyncThunk(
'model/fetchGetAllModels',
async (
token,
thunkAPI
) => {
return await abstractService._getList(endpoint, token)
}
)
/**
* @param body:
* param token: base64 token,
* param id: model id
*/
const fetchGetOneModelAndDownload = createAsyncThunk(
'model/fetchGetOneModelAndDownload',
async (
body,
thunkAPI
) => {
return await abstractService._getOne(
endpoint,
body.id,
body.token
)
}
)
/**
* @param body:
* param token: base64 token,
* param file: file binary
* param user_id: user id
*/
const fetchUploadModel = createAsyncThunk(
'model/fetchUploadModel',
async (
body,
thunkAPI
) => {
return await abstractService.axiosFilePost(
endpoint,
body,
body.token
)
}
)
export default {
fetchGetAllModels,
fetchGetOneModelAndDownload,
fetchUploadModel
}

View File

@ -1,39 +0,0 @@
import { createAsyncThunk } from '@reduxjs/toolkit'
import abstractService from './abstracts/abstractService'
let endpoint = '/render/'
const fetchGetAllRenders = createAsyncThunk(
'render/fetchGetAllRenders',
async (
token,
thunkAPI
) => {
return await abstractService._getList(endpoint, token)
}
)
/**
* @param body:
* param token: base64 token,
* param id: render id
*/
const fetchGetOneRenderAndDownload = createAsyncThunk(
'render/fetchGetOneRenderAndDownload',
async (
body,
thunkAPI
) => {
return await abstractService._getOne(
endpoint,
body.id,
body.token
)
}
)
export default {
fetchGetAllRenders,
fetchGetOneRenderAndDownload
}

View File

@ -1,113 +0,0 @@
import { createAsyncThunk } from '@reduxjs/toolkit'
import GeneralAddress from './abstracts/abstractAddress'
let endpoint_single_image = '/render/single/image/'
let endpoint_single_set = '/render/single/set/'
let endpoint_all = '/render/all/'
let endpoint_vector_single_image = '/render/vector/single/image/'
let endpoint_vector_single_set = '/render/vector/single/set/'
const __uuidv4 = () => {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
/[xy]/g,
(c) => {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
}
)
}
/**
*
* @param {string} endpoint:
* examples:
* 'image' - connect to single image ws renderer
* 'set' - connect to single set ws renderer
* 'all' - connect to all ws renderer
*
* 'vector/image' - connect to vector single image ws renderer
* 'vector/set' - connerct to vector single set ws renderer
*/
const __make_address = async (endpoint) => {
if (endpoint === 'image')
endpoint = endpoint_single_image
else if (endpoint === 'set')
endpoint = endpoint_single_set
else if (endpoint === 'all')
endpoint = endpoint_all
else if (endpoint === 'vector/image')
endpoint = endpoint_vector_single_image
else if (endpoint === 'vector/set')
endpoint = endpoint_vector_single_set
return GeneralAddress + endpoint
}
/**
* @param body:
* param token: token
* param endpoint:
* examples:
* 'image' - connect to single image ws renderer
* 'set' - connect to single set ws renderer
* 'all' - connect to all ws renderer
*
* 'vector/image' - connect to vector single image ws renderer
* 'vector/set' - connerct to vector single set ws renderer
*/
const fetchConnect = createAsyncThunk(
'render/async/fetchConnect',
async (
body,
thunkAPI
) => {
let uuid = __uuidv4()
let address = __make_address(body.endpoint)
return {
web_socket: new WebSocket(address + uuid),
address: address,
room_uuid: uuid
}
}
)
/**
* @param body:
* param token: token
* param message: message string
*/
const fetchSaveMessage = createAsyncThunk(
'render/async/fetchSaveMessage',
async (
body,
thunkAPI
) => {
return {
message: body
}
}
)
/**
* @param body:
* param token: token
*/
const fetchDisconnect = createAsyncThunk(
'render/async/fetchDisconnect',
async (
token,
thunkAPI
) => {
return {
web_socket: null,
}
}
)
export default {
fetchConnect,
fetchSaveMessage,
fetchDisconnect
}

View File

@ -1,46 +0,0 @@
import { createAsyncThunk } from '@reduxjs/toolkit'
import abstractService from './abstracts/abstractService'
let endpoint = '/user/auth'
/**
* @param body:
* param username: username string
* param password: password string
*/
const fetchLogin = createAsyncThunk(
'user/auth/fetchLogin',
async (
body,
thunkAPI
) => {
return await abstractService._post(
endpoint,
body,
''
)
}
)
/**
* @param body:
* param token: user token
*/
const fetchLogout = createAsyncThunk(
'user/auth/fetchLogout',
async (
token,
thunkAPI
) => {
return await abstractService._delete(
endpoint,
'',
token
)
}
)
export default {
fetchLogin,
fetchLogout
}

View File

@ -1,108 +0,0 @@
import { createAsyncThunk } from '@reduxjs/toolkit'
import abstractService from './abstracts/abstractService'
let endpoint = '/user/'
const fetchGetAllUsers = createAsyncThunk(
'user/fetchGetAllUsers',
async (
token,
thunkAPI
) => {
return await abstractService._getList(
endpoint,
token
)
}
)
/**
* @param body:
* param token: token
* param user_id: user_id
*/
const fetchGetOneUser = createAsyncThunk(
'user/fetchGetAllUsers',
async (
body,
thunkAPI
) => {
return await abstractService._getOne(
endpoint,
body.user_id,
body.token
)
}
)
/**
* @param body:
* param username: username string
* param password: password string
* param email: email string
*/
const fetchRegister = createAsyncThunk(
'user/fetchRegister',
async (
body,
thunkAPI
) => {
return await abstractService._post(
endpoint,
body,
''
)
}
)
/**
* @param body:
* param token: token
* param user_id: user_id
* param user:
* param username: username
* param password: password
* param email: email
*/
const fetchUpdateUser = createAsyncThunk(
'user/fetchRegister',
async (
body,
thunkAPI
) => {
return await abstractService._patch(
endpoint,
body.user_id,
body.user,
body.token
)
}
)
/**
* @param body:
* param user_id: user_id
* param token: user token
*/
const fetchDeleteUser = createAsyncThunk(
'user/fetchRegister',
async (
body,
thunkAPI
) => {
return await abstractService._delete(
endpoint,
body.user_id,
body.token
)
}
)
export default {
fetchGetAllUsers,
fetchGetOneUser,
fetchRegister,
fetchUpdateUser,
fetchDeleteUser
}

View File

@ -1,29 +0,0 @@
import { createSlice } from '@reduxjs/toolkit'
import modelCrudAsyncThunk from '../asyncThunks/modelCrudAsyncThunk'
const modelCrudSlice = createSlice(
{
name: 'model',
initialState: {
models_list: [],
download_blend_file: '',
upload_blend_file_status: ''
},
reducers: {},
extraReducers: {
[modelCrudAsyncThunk.fetchGetAllModels.fulfilled.type]: (state, action) => {
state.models_list = action.payload.data
},
[modelCrudAsyncThunk.fetchGetOneModelAndDownload.fulfilled.type]: (state, action) => {
state.download_blend_file = action.payload.data
},
[modelCrudAsyncThunk.fetchUploadModel.fulfilled.type]: (state, action) => {
state.upload_blend_file_status = action.payload.data
}
}
}
)
export const modelCrudReducer = modelCrudSlice.reducer
export const modelCrudSelector = state => state.modelCrudReducer

View File

@ -1,25 +0,0 @@
import { createSlice } from '@reduxjs/toolkit'
import renderCrudAsyncThunk from '../asyncThunks/renderCrudAsyncThunk'
const renderCrudSlice = createSlice(
{
name: 'render',
initialState: {
render_list: [],
download_zip_file: ''
},
reducers: {},
extraReducers: {
[renderCrudAsyncThunk.fetchGetAllRenders.fulfilled.type]: (state, action) => {
state.render_list = action.payload.data
},
[renderCrudAsyncThunk.fetchGetOneRenderAndDownload.fulfilled.type]: (state, action) => {
state.download_zip_file = action.payload.data
}
}
}
)
export const renderCrudReducer = renderCrudSlice.reducer
export const renderCrudSelector = state => state.renderCrudReducer

View File

@ -1,73 +0,0 @@
import { createSlice } from '@reduxjs/toolkit'
import renderWebsocketAsyncThunk from '../asyncThunks/renderWebsocketAsyncThunk'
import { GeneralAddressWS } from '../asyncThunks/abstracts/abstractAddress'
const __uuidv4 = () => {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
/[xy]/g,
(c) => {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
}
)
}
const initialState = {
web_socket_address: '',
address: '',
room_uuid: '',
messages: [],
percents: 0.0,
connected: false
}
const renderWebsocketSlice = createSlice(
{
name: 'render/async',
initialState,
reducers: {
connect(state, action) {
state.room_uuid = __uuidv4()
state.address = GeneralAddressWS + action.payload.address
state.web_socket_address = state.address + state.room_uuid
state.messages = []
state.percents = 0.0
state.connected = true
},
saveMessage(state, action) {
state.messages = [
...state.messages,
action.payload.message
]
if (
(
!isNaN(action.payload.message.info)
&& action.payload.message.info.toString().indexOf('.') != -1
) || action.payload.message.info === 'render success'
) {
state.percents = action.payload.message.info
}
},
resetMessages(state) {
state.messages = []
state.percents = ''
},
disconnect(state) {
state.web_socket_address = ''
state.address = ''
state.room_uuid = ''
state.messages = []
state.connected = false
}
},
extraReducers: {}
}
)
export const renderWebsocketReducer = renderWebsocketSlice.reducer
export const { connect, saveMessage, disconnect } = renderWebsocketSlice.actions
export const renderWebsocketSelector = state => state.renderWebsocketReducer

View File

@ -1,52 +0,0 @@
import { createSlice } from '@reduxjs/toolkit'
import userAuthAsyncThunk from '../asyncThunks/userAuthAsyncThunk'
const userAuthSlice = createSlice(
{
name: 'user/auth',
initialState: {
token: '',
user: {
id: 0,
username: '',
email: ''
},
info: ''
},
reducers: {
deleteUser(state) {
state.token = ''
state.user.id = 0
state.user.username = ''
state.user.email = ''
state.info = 'user has been deleted'
}
},
extraReducers: {
[userAuthAsyncThunk.fetchLogin.fulfilled.type]: (state, action) => {
try {
state.token = action.payload.data.Authorization
state.user.id = action.payload.data.user.id
state.user.username = action.payload.data.user.username
state.user.email = action.payload.data.user.email
state.info = 'login success'
} catch {
state.info = 'login failed'
}
},
[userAuthAsyncThunk.fetchLogout.fulfilled.type]: (state, action) => {
state.token = ''
state.user.id = 0
state.user.username = ''
state.user.email = ''
state.info = action.payload.data.info
}
}
}
)
export const userAuthReducer = userAuthSlice.reducer
export const { deleteUser } = userAuthSlice.actions
export const userAuthSelector = state => state.userAuthReducer

View File

@ -1,47 +0,0 @@
import { createSlice } from '@reduxjs/toolkit'
import userCrudAsyncThunk from '../asyncThunks/userCrudAsyncThunk'
const userCrudSlice = createSlice(
{
name: 'user',
initialState: {
users_list: [],
user_get: {},
user_register: {
id: -1,
username: '',
email: ''
},
user_update: {},
user_delete: '',
info: ''
},
reducers: {},
extraReducers: {
[userCrudAsyncThunk.fetchGetAllUsers.fulfilled.type]: (state, action) => {
state.users_list = action.payload.data
},
[userCrudAsyncThunk.fetchGetOneUser.fulfilled.type]: (state, action) => {
state.user_get = action.payload.data
},
[userCrudAsyncThunk.fetchRegister.fulfilled.type]: (state, action) => {
state.user_register = action.payload.data
state.info = 'register success'
},
[userCrudAsyncThunk.fetchUpdateUser.fulfilled.type]: (state, action) => {
state.user_update = action.payload.data
},
[userCrudAsyncThunk.fetchDeleteUser.fulfilled.type]: (state) => {
state.users_list = []
state.user_get = {}
state.user_register = {}
state.user_update = {}
state.user_delete = 'true'
}
}
}
)
export const userCrudReducer = userCrudSlice.reducer
export const userCrudSelector = state => state.userCrudReducer

View File

@ -1,36 +0,0 @@
export const loadState = () => {
if ( typeof window !== 'undefined' ) {
try {
const serializedState = localStorage.getItem('state')
if (serializedState === undefined || serializedState === null) {
return {}
} else {
return JSON.parse(serializedState)
}
} catch (err) {
console.log(err)
return undefined
}
}
};
export const saveState = (state) => {
if ( typeof window !== 'undefined' ) {
try {
const serializedState = JSON.stringify(state)
if (serializedState === null) {
return undefined
} else {
localStorage.setItem('state', serializedState)
}
} catch (err) {
console.log('save in local storage error')
}
}
};

View File

@ -1,37 +0,0 @@
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import { loadState, saveState } from './stateLoader'
import lodash from 'lodash'
import { modelCrudReducer } from './slices/modelCrudSlice'
import { renderCrudReducer } from './slices/renderCrudSlice'
import { renderWebsocketReducer } from './slices/renderWebsocketSlice'
import { userAuthReducer } from './slices/userAuthSlice'
import { userCrudReducer } from './slices/userCrudSlice'
let persistedState = loadState()
export const store = configureStore({
reducer: {
modelCrudReducer,
renderCrudReducer,
renderWebsocketReducer,
userAuthReducer,
userCrudReducer
},
preloadedState: persistedState,
middleware: getDefaultMiddleware (
{
serializableCheck: false,
}
),
})
store.subscribe(() => {
saveState(store.getState());
});
store.subscribe(lodash.throttle(() => {
saveState(store.getState())
}, 100))

View File

@ -0,0 +1,50 @@
$cube-size: 400px;
$cube-color: rgba(0, 140, 0, 0.5);
$perspective: 10000px;
$animation-duration: 20s;
@mixin cube-face {
position: absolute;
width: $cube-size - 15px;
height: $cube-size - 15px;
background: $cube-color;
will-change: transform;
}
@keyframes rotateCube {
0% {
transform: rotateX(0) rotateY(0) rotateZ(0);
}
100% {
transform: rotateX(360deg) rotateY(360deg) rotateZ(360deg);
}
}
.graphic-container {
perspective: $perspective;
perspective-origin: 50% 100px; // Adjusted for better 3D effect
z-index: 1; // Lower z-index than the login form to place it behind
}
.cube {
width: $cube-size;
height: $cube-size;
position: relative;
margin: auto; // Centers the cube within the graphic container
transform-style: preserve-3d;
transform-origin: center center; // Rotates around the center of the cube
animation: rotateCube $animation-duration infinite linear;
will-change: transform;
div {
@include cube-face;
}
.front { transform: translateZ($cube-size / 2); }
.back { transform: translateZ(-$cube-size / 2) rotateY(180deg); }
.right { transform: rotateY(90deg) translateZ($cube-size / 2); }
.left { transform: rotateY(-90deg) translateZ($cube-size / 2); }
.top { transform: rotateX(90deg) translateZ($cube-size / 2); }
.bottom { transform: rotateX(-90deg) translateZ($cube-size / 2); }
}

View File

@ -0,0 +1,103 @@
// Define common variables
$background-base: rgba(51,54,51,1);
$header-background: 0;
$form-background: rgba(0,0,0,0.5);
$header-color: white;
$button-background: green;
$border-color: green;
$input-background: #222;
$font-family-default: neue-haas-unica, sans-serif;
$login-form-font-color: #a6a6a6;
body, html {
height: 100%;
width: 100%;
margin: 0;
font-family: $font-family-default;
font-weight: 680;
tab-size: 4;
background: $background-base;
color: white;
display: flex;
justify-content: center; // Center horizontally
align-items: center; // Center vertically
}
.header {
text-align: center;
padding: 20px;
background: $header-background;
color: $header-color;
z-index: 3; // Ensure the login form is above the cube
position: relative; // Required for z-index to take effect
}
.login-container {
display: flex;
flex-direction: column;
margin-top: 0%;
border-radius: 5px;
.main-content {
//flex: 1;
//display: flex;
margin-top: 0%;
align-items: center;
justify-content: space-evenly;
.login-form {
background: $form-background;
padding: 50px;
width: 350px;
color: $login-form-font-color;
// border: 2px solid $border-color;
border-radius: 10px;
margin-top: -400px;
margin-right: auto;
margin-left: auto;
z-index: 2; // Ensure the login form is above the cube
position: relative; // Required for z-index to take effect
.form-field {
margin-bottom: 15px;
label {
display: block;
margin-bottom: 15px;
}
input {
width: 90%;
padding: 5%;
background: $input-background;
border: 1px solid $border-color;
border-radius: 5px;
color: white;
}
}
button {
padding: 5%;
width: 100%;
margin-top: 30px;
border-radius: 5px;
background: $button-background;
font-family: $font-family-default;
font-weight: 800;
color: rgba(0,0,0,0.5);
border: none;
cursor: pointer;
}
}
.graphic-container {
width: 400px;
height: 400px;
margin-right: auto;
margin-left: auto;
z-index: 1; // Lower z-index than the login form to place it behind
}
}
}