Compare commits

..

No commits in common. "feat/x_gpu/chat_gpt_new_version" and "master" have entirely different histories.

75 changed files with 12603 additions and 35987 deletions

View File

@ -1,3 +0,0 @@
node_modules/
.cache/

1
.env
View File

@ -1 +0,0 @@
REACT_APP_API_URL=http://localhost:8000

2
.gitignore vendored
View File

@ -1,3 +1,3 @@
node_modules/
.cache/
public/
public

View File

@ -1,11 +0,0 @@
FROM nginx:latest
WORKDIR /
RUN rm /usr/share/nginx/html/*
COPY ./public ./usr/share/nginx/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

View File

@ -1,9 +0,0 @@
FROM node:18.19.1-alpine
WORKDIR /app
COPY . ./
RUN npm install --silent --force
CMD ["npm", "run", "build"]

View File

@ -1,13 +0,0 @@
server {
listen 80;
listen [::]:80;
root /var/www/work_front/html;
index index.html index.htm index.nginx-debian.html;
server_name work_front www.work_front;
location / {
try_files $uri $uri/ =404;
}
}

View File

@ -1,9 +0,0 @@
import React from 'react';
import { Provider } from 'react-redux';
import { store } from './src/redux/store';
export const wrapRootElement = ({ element }) => (
<Provider store={store}>
{element}
</Provider>
);

View File

@ -1,9 +0,0 @@
import React from 'react';
import { Provider } from 'react-redux';
import { store } from './src/redux/store';
export const wrapRootElement = ({ element }) => (
<Provider store={store}>
{element}
</Provider>
);

38524
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,24 +8,17 @@
"gatsby"
],
"scripts": {
"develop": "gatsby develop --host=0.0.0.0",
"start": "gatsby develop --host=0.0.0.0",
"develop": "gatsby develop",
"start": "gatsby develop",
"build": "gatsby build",
"serve": "gatsby serve",
"clean": "gatsby clean"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^6.7.2",
"@reduxjs/toolkit": "^2.6.0",
"axios": "^1.8.1",
"gatsby": "^5.13.3",
"gatsby-plugin-sass": "^6.14.0",
"js-cookie": "^3.0.5",
"react": "^18",
"react-dom": "^18",
"react-redux": "^9.2.0",
"react-router-dom": "^7.1.5",
"react-tsparticles": "^2.12.2",
"gatsby": "^2.32.3",
"gatsby-plugin-sass": "^3.2.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"sass": "^1.32.7"
}
}

View File

@ -1,59 +0,0 @@
// src/App.js
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import LoginPage from './pages/auth/login';
import RegisterPage from './pages/auth/register';
import DashboardPage from './pages/dashboard';
import LandingPage from './pages/landing';
import NotFoundPage from './pages/404';
import FormLogin from './pages/FormLogin';
import FormRegister from './pages/FormRegister';
import FormModels from './pages/FormModels';
import FormRenders from './pages/FormRenders';
import FormAi from './pages/FormAi';
function App() {
return (
<Router>
<nav style={{ margin: '1rem' }}>
<Link to="/login" style={{ marginRight: '10px' }}>
Login
</Link>
<Link to="/register" style={{ marginRight: '10px' }}>
Register
</Link>
<Link to="/landing" style={{ marginRight: '10px' }}>
Offer
</Link>
<Link to="/dashboard" style={{ marginRight: '10px' }}>
Dashboard
</Link>
<Link to="/models" style={{ marginRight: '10px' }}>
Models
</Link>
<Link to="/renders" style={{ marginRight: '10px' }}>
Renders
</Link>
<Link to="/ai-tasks" style={{ marginRight: '10px' }}>
AI Tasks
</Link>
</nav>
<Routes>
<Route path="/" element={<LoginPage />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/register" element={<RegisterPage />} />
<Route path="/landing" element={<LandingPage />} />
<Route path="/dashboard/*" element={<DashboardPage />} />
<Route path="/models" element={<FormModels />} />
<Route path="/renders" element={<FormRenders />} />
<Route path="/ai-tasks" element={<FormAi />} />
<Route path="*" element={<NotFoundPage />} />
</Routes>
</Router>
);
}
export default App;

View File

@ -1,91 +0,0 @@
import React from 'react';
import '../styles/general.scss';
import SmallCubeComponent from './smallCube.js';
const FootComponent = () => {
return (
<footer>
<div className="content-container">
<div className="content">
<div className="section">
<SmallCubeComponent />
</div>
<div className="section">
<h4>
<a>
BUSINESS
</a>
</h4>
<h4>
<a>
SIGN IN
</a>
</h4>
<h4>
<a>
SIGN UP
</a>
</h4>
</div>
</div>
<div className="content">
<div className="section">
<h4>
Company
</h4>
</div>
<div className="section">
<a>
About Us
</a>
</div>
<div className="section">
<a>
Contact Us
</a>
</div>
</div>
<div className="content">
<div className="section">
<h4>
Resources
</h4>
</div>
<div className="section">
<a>
Blog
</a>
</div>
<div className="section">
<a>
Help Center
</a>
</div>
</div>
<div className="content">
<div className="section">
</div>
</div>
<div className="content">
<div className="section">
</div>
</div>
<div className="content">
<div className="section">
</div>
</div>
</div>
<div className="bottom">
<p>
&copy; {new Date().getFullYear()} FehuDev. All rights reserved.
</p>
</div>
</footer>
)
}
export default FootComponent

View File

@ -1,68 +0,0 @@
import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { userAuthSelector } from '../../../redux/slices/userAuthSlice'
import { modelCrudSelector } from '../../../redux/slices/modelCrudSlice'
import modelCrudAsyncThunk from '../../../redux/asyncThunks/modelCrudAsyncThunk'
import { GeneralAddress } from '../../../redux/asyncThunks/abstracts/abstractAddress'
import FormGenerator from '../formGenerator'
const ModelShowAndDownloadForm = () => {
const dispatch = useDispatch()
const { models_list } = useSelector( modelCrudSelector )
const { user, token } = useSelector( userAuthSelector )
let blocker = false
useEffect(
() => {
if ( models_list.length === 0 && user.id > 0 && token !== '' && !blocker ) {
dispatch( modelCrudAsyncThunk.fetchGetAllModels(token) )
if ( models_list.length === 0 ) {
blocker = true
}
}
}
)
let inputList = [
{
type: 'info',
action: 'Download',
endpint: 'model/download',
button_value: 'Refresh Models List'
},
{
type: 'links-listing',
name: 'Models',
values: models_list,
link: GeneralAddress + '/model/',
}
]
const handleRefresh = () => {
dispatch( modelCrudAsyncThunk.fetchGetAllModels(token) )
}
return (
<div
className="float_form_model"
style={ { marginTop: '10%' , overflowY: 'scroll', height: '500px' } }
>
<FormGenerator
inputList={ inputList }
refList={ [] }
action={ handleRefresh }
/>
</div>
)
}
export default ModelShowAndDownloadForm

View File

@ -1,69 +0,0 @@
import React, { useState } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { userAuthSelector } from '../../../redux/slices/userAuthSlice'
import { threeDModelCrudSelector } from '../../../redux/slices/threeDModelCrudSlice'
import { uploadModel } from '../../../redux/asyncThunks/threeDModelCrudAsyncThunk'
import FormGenerator from '../formGenerator'
const ModelUploadForm = () => {
const dispatch = useDispatch()
const [blend, setBlend] = useState('')
const [blendInfo, setBlendInfo] = useState('Drop/Click\nfor upload "*.blend" file')
const { upload_blend_file_status } = useSelector( threeDModelCrudSelector )
const { user, token } = useSelector( userAuthSelector )
const inputList = [
{
type: 'info',
action: 'Upload',
endpoint: 'model/upload',
button_value: 'Upload Model'
},
{
type: 'file',
name: 'Model',
fileType: 'blender',
dropInfo: blendInfo,
setDropInfo: setBlendInfo,
file: blend,
setFile: setBlend
}
]
const handleModelUpload = () => {
if (!blend) {
return;
}
dispatch( uploadModel({
user_id: user.id,
file: blend,
token: token
}));
}
return (
<div>
<FormGenerator
inputList={ inputList }
refList={ [] }
action={ handleModelUpload }
/>
<p>
{
typeof upload_blend_file_status === 'string'
? ''
: 'info' in upload_blend_file_status
? upload_blend_file_status.info
: ''
}
</p>
</div>
)
}
export default ModelUploadForm

View File

@ -1,265 +0,0 @@
import React, { useState, useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { renderWebsocketSelector } from '../../redux/slices/renderWebsocketSlice'
import { connect, saveMessage, resetMessages, disconnect } from '../../redux/slices/renderWebsocketSlice'
import FormGenerator from './formGenerator'
const ProgressBar = () => {
const {
percents,
connect
} = useSelector( renderWebsocketSelector )
return (
<div className="progress_bar_form">
<div>
{
typeof percents === 'number'
? 'Progress: ' + percents + '%'
: percents
}
</div>
<div>
{
!isNaN(percents)
&& percents.toString().indexOf('.') != -1
? <div
className='progress_bar_progress'
style={ { width: percents + '%', height: '100%', backgroundColor: 'green' } }
>
</div>
: percents === 'render success'
? <div
className='progress_bar_progress'
style={ { width: '100%', height: '100%', backgroundColor: 'green' } }
>
</div>
: <></>
}
</div>
</div>
)
}
const AbstractWebsocket = ({ addressWS, inputList, refList, bodyComparer }) => {
const [web_socket, setWebsocket] = useState(null)
const dispatch = useDispatch()
const {
web_socket_address,
address,
room_uuid,
messages,
connected
} = useSelector( renderWebsocketSelector )
const handleConnect = ( event ) => {
event.preventDefault()
if ( web_socket === null && address === '' && room_uuid === '') {
dispatch(
connect(
{
address: addressWS
}
)
)
}
}
const handleSendMessage = ( refs ) => {
let body = bodyComparer( refs )
console.log( body )
try {
dispatch(
saveMessage(
{
message: { info: 0 } // start
}
)
)
web_socket.send(
JSON.stringify(
body
)
)
} catch (error) {
web_socket.close()
dispatch(
disconnect()
)
setWebsocket(null)
console.log(error)
}
}
const handleDisconnect = ( event ) => {
event.preventDefault()
if ( web_socket !== null && address !== '' && room_uuid !== '' ) {
try {
web_socket.close()
dispatch(
disconnect()
)
} catch (error) {
console.log(error)
}
} else if ( address !== '' && room_uuid !== '' ) {
dispatch(
disconnect()
)
}
setWebsocket(null)
console.log('disconnect')
}
useEffect(
() => {
if ( web_socket_address !== '' && web_socket === null ) {
console.log( 'connect' )
setWebsocket(new WebSocket( web_socket_address ))
}
if ( web_socket !== null ) {
web_socket.onmessage = (event) => {
console.log( event.data )
if ( messages[ messages.length - 1 ] !== JSON.parse( event.data ) ) {
dispatch(
saveMessage(
{
message: JSON.parse( event.data )
}
)
)
}
}
}
}
)
return (
<div>
<div
className="float_form_render_async"
style={
connected
? addressWS === '/vector/single/set/' || addressWS === '/vector/single/image/'
? { marginTop: '10%', overflowY: 'scroll' }
: { marginTop: '10%' }
: { marginTop: '100%' }
}
>
<FormGenerator
inputList={ inputList }
refList={ refList }
action={ handleSendMessage }
/>
</div>
<div className="float_form_connect">
<p>
{ addressWS }
</p>
<ProgressBar />
{
connected
?
<button onClick={ (event) => handleDisconnect(event) }>
Disconnect
</button>
:
<button onClick={ (event) => handleConnect(event) }>
Connect
</button>
}
</div>
<div
className="float_form_console"
style={ connected ? { marginTop: '25%', height: '200px' } : { marginTop: '15%', height: '10px' } }
>
<p>
console:
</p>
<div className="console_data">
{
messages.slice(0).reverse().map( (item) => {
return (
<div>
<>
{
Object.keys(item).map( (key) => {
if ( key == 'details' ) {
return (
<>
{
Object.keys(item[key]).map( (keyTwo) => {
return (
<div>
{ ' ' + keyTwo + ': ' + item[key][keyTwo] + ' ' }
</div>
)
}
)
}
</>
)
} else if ( key === 'image' ) {
return (
<img
src={ 'data:image/png;base64, ' + item[key] }
style={ { width: '300px', height: '150px' } }
/>
)
} else {
return (
<>
{ key + ': ' + item[key] + ' ' }
</>
)
}
}
)
}
</>
</div>
)
}
)
}
</div>
</div>
</div>
)
}
export default AbstractWebsocket

View File

@ -1,71 +0,0 @@
import React, { useState } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { userAuthSelector } from '../../../redux/slices/userAuthSlice'
import { aiModelCrudSelector } from '../../../redux/slices/aiModelCrudSlice'
import { uploadModel } from '../../../redux/asyncThunks/aiModelCrudAsyncThunk'
import FormGenerator from '../formGenerator'
const AIModelUploadForm = () => {
const dispatch = useDispatch()
const [model, setModel] = useState('')
const [modelInfo, setModelInfo] = useState('Drop/Click\nfor upload AI model file')
const { upload_model_status } = useSelector(aiModelCrudSelector)
const { user, token } = useSelector(userAuthSelector)
const inputList = [
{
type: 'info',
action: 'Upload',
endpoint: 'ai-model/upload',
button_value: 'Upload AI Model'
},
{
type: 'file',
name: 'Model',
fileType: 'ai',
dropInfo: modelInfo,
setDropInfo: setModelInfo,
file: model,
setFile: setModel
}
]
const handleModelUpload = () => {
if (!model) {
return;
}
dispatch(uploadModel({
user_id: user.id,
file: model,
token: token
}));
}
return (
<div>
<FormGenerator
inputList={inputList}
refList={[]}
action={handleModelUpload}
/>
<p>
{
!upload_model_status
? ''
: typeof upload_model_status === 'string'
? ''
: 'info' in upload_model_status
? upload_model_status.info
: ''
}
</p>
</div>
)
}
export default AIModelUploadForm

View File

@ -1,674 +0,0 @@
import React, { useState, useEffect } from 'react'
import passwordVisibleImg from '../../images/password-visible.png'
import passwordHiddenImg from '../../images/password-hidden.png'
/**
*
* @param { [ {}, {}, ...{} ] } inputList - list of dicts with info about input
* @param { } action - fetch method
*/
export const FormGenerator = ({
inputList,
action
}) => {
const handleSubmit = (e) => {
e.preventDefault();
const formData = {};
inputList.forEach((singleInput, index) => {
if (typeof singleInput.type !== 'undefined' && singleInput.ref?.current) {
formData[singleInput.name] = singleInput.ref.current.value;
}
});
action(formData);
};
let info
return (
<form onSubmit={handleSubmit} className="form">
{
inputList.map((input, key) => {
if (input.type === 'info') {
info = input
} else if (input.type === 'text') {
return (
<TextInputGenerator
input={input}
info={info}
key={key}
/>
)
} else if (input.type === 'password') {
return (
<PasswordInputGenerator
input={input}
info={info}
key={key}
/>
)
} else if (input.type === 'links-listing') {
return (
<DownloadFilesListInputGenerator
input={input}
info={info}
key={key}
/>
)
} else if (input.type === 'file') {
return (
<UploadInputGenerator
input={input}
info={info}
key={key}
/>
)
} else if (input.type === 'choice-listing') {
return (
<ChoiceListingGenerator
input={input}
info={info}
key={key}
/>
)
} else if (input.type === 'range') {
return (
<RangeInputGenerator
input={input}
info={info}
key={key}
/>
)
} else if (input.type === 'vector') {
return (
<VectorInputGenerator
input={input}
info={info}
key={key}
/>
)
} else if (input.type === 'label') {
return (
<div className="form-field">
<label>{input.name}</label>
<div className="label-value">{input.value}</div>
</div>
)
}
})
}
{
info.button_value === ''
? <></>
: <button
type='submit'
disabled={!info.allowButtonAction}
className={!info.allowButtonAction ? "button-disabled" : ""}
>
{info.button_value}
</button>
}
</form>
)
}
/**
* Text input generator, example:
* @param {
* {
* type: 'text',
* name: 'name',
* ref: React.createRef(),
* onChange: null OR validationFunc
* validationInfo: null OR useState("")
* } } input - basic text input
* @param {
* {
* type: 'info',
* action: 'Update',
* endpoint: 'Album'
* } } info - information about form
*/
const TextInputGenerator = ({
input, info
}) => {
const [textInputValidationInfo, setTextInputValidationInfo] = useState("Empty")
const inputRegex = /^[^'";<>=]+$/
const defaultValidation = (event) => {
if (event.target.value === "") {
setTextInputValidationInfo("Empty")
} else if (!inputRegex.test(event.target.value)) {
setTextInputValidationInfo("Please provide correct value")
} else {
setTextInputValidationInfo("Success")
}
input.validationInfo = textInputValidationInfo
}
return (
<div className="form-field">
<label>
{input.name}
</label>
<input
id={input.name + info.action + info.endpoint + 'Input'}
autoComplete='off'
ref={input.ref}
onChange={input.onChange === null ? defaultValidation : input.onChange}
className={
[ "Empty", "Success"].includes(
input.validationInfo === null ? textInputValidationInfo : input.validationInfo
) ? "" : "input-incorrect"
}
placeholder={input.placeholder === null ? "" : input.placeholder}
/>
<div
className="popup"
style={
[ "Empty", "Success"].includes(
input.validationInfo === null ? textInputValidationInfo : input.validationInfo
) ? {"display": "none", "height": "0px"} : {"display": "block"}
}
>
<div className="popup-content">
{ input.validationInfo === null ? textInputValidationInfo : input.validationInfo }
</div>
</div>
</div>
)
}
/**
* Text input generator, example:
* @param {
* {
* type: 'password',
* name: 'name',
* ref: React.createRef()
* } } input - basic text input
* @param {
* {
* type: 'info',
* action: 'Update'
* endpoint: 'Album'
* } } info - information about form
*/
const PasswordInputGenerator = ({
input, info
}) => {
const [contentIsHidden, setContentIsHidden] = useState(true)
return (
<div className="form-field">
<label>
{ input.name }
</label>
<div className="horizontal-container-input">
<input
id={input.name + info.action + info.endpoint + 'Input'}
autoComplete='off'
ref={input.ref}
type={ contentIsHidden ? 'password' : 'text' }
onChange={input.onChange}
className={ [ "Empty", "Success"].includes(input.validationInfo) ? "" : "input-incorrect" }
/>
<img
src={ contentIsHidden ? passwordHiddenImg : passwordVisibleImg }
className={ [ "Empty", "Success"].includes(input.validationInfo) ? "" : "input-visible-incorrect" }
onClick={ () => { setContentIsHidden(!contentIsHidden) } }
/>
</div>
<div
className="popup"
style={ [ "Empty", "Success"].includes(input.validationInfo) ? {"display": "none", "height": "0px"} : {"display": "block"} }
>
<div className="popup-content">
{ input.validationInfo }
</div>
</div>
</div>
)
}
const ObjectIterator = ({
object, divPlacer
}) => {
return(
<>
{
typeof object == "object" ?
Object.keys( object ).map(
( key ) => {
return (
<div key={ key }>
{ divPlacer( object[key] ) }
</div>
)
}
)
:
object
}
</>
)
}
/**
* Text input generator, example:
* @param {
* {
* type: 'drop-box',
* name: 'name',
* values: list,
* link: link to the file
* } } input - basic text input
* @param {
* {
* type: 'info',
* action: 'Update'
* endpoint: 'Album'
* } } info - information about form
*/
const DownloadFilesListInputGenerator = ({
input, info
}) => {
return (
<div
id={input.name + info.action + info.endpoint + 'DropBox'}
>
{input.name + ':'}
{
input.values.length == 0 ?
() => {
return (
<div>
empty
</div>
)
}
: input.values.map( (item, index) => {
return (
<>
<div
key={ info.action + '_element_' + index }
ls={ item }
>
{
typeof item == 'string' ?
item
: Object.keys(item).map(
( key, index ) => {
return(
<div style={{ paddingLeft: '10px' }}>
{ key + ': ' }
{
typeof item[key] === "object" ?
Object.keys( item[key] ).map(
( key_two, index ) => {
return (
<div style={{ paddingLeft: '20px' }}>
{ key_two + ': '}
{
typeof item[key][key_two] == 'object' ?
Object.keys( item[key][key_two] ).map(
(key_three, index) => {
return (
<div style={{ paddingLeft: '30px' }}>
{ key_three + ": " }
{ "x: " + item[key][key_two][key_three].x + ", " }
{ "y: " + item[key][key_two][key_three].y + ", " }
{ "z: " + item[key][key_two][key_three].z + ", " }
</div>
)
}
)
:
item[key][key_two]
}
</div>
)
}
)
:
item[key]
}
</div>
)
}
)
}
<br />
<br />
<a
href={ input.link + index + '/' }
>
download
</a>
</div>
<div style={{ width: '100%', height: '1px', backgroundColor: '#008000' }}>
</div>
</>
)
}
)
}
</div>
)
}
/**
* Text input generator, example:
* @param {
* {
* type: 'choice-listing',
* name: 'name',
* values: list,
* ref: React.createRef()
* } } input - basic text input
* @param {
* {
* type: 'info',
* action: 'Update'
* endpoint: 'Album'
* } } info - information about form
*/
const ChoiceListingGenerator = ({
input, info
}) => {
const __handleRef = ( event ) => {
event.preventDefault()
input.ref.current = {
value: event.target.value
}
}
return (
<div
id={input.name + info.action + info.endpoint + 'ChoiceListing'}
>
{input.name + ':'}
<select
onChange={ (event) => __handleRef( event ) }
>
<option
value={ '--Select-Model--' }
>
--Select-Model--
</option>
{
input.values.map( (item) => {
return (
<option
key={ item.model }
value={ item.model }
>
{ item.model.replace('.blend', '') }
</option>
)
}
)
}
</select>
</div>
)
}
/**
* Upload file input generator, example:
* @param {
* {
* type: 'file',
* name: 'name',
* endpoint: 'Album',
* fileType: 'image' or 'audio',
* dropInfo: dropInfo, setDropInfo: setDropInfo(), #useState
* file: file, setFile: setFile() #useState
* } } input -
*/
const UploadInputGenerator = ({
input, info
}) => {
const onLoadFile = async (event) => {
event.preventDefault()
let data = event.target.files[0]
input.setFile( data )
setDropInfos(data.name, data.size)
}
const onLoadFileDrop = async (event) => {
event.preventDefault()
event.persist()
let data = event.dataTransfer.files[0]
input.setFile( data )
setDropInfos(data.name, data.size)
}
const toBase64 = async (file) => new Promise((resolve, reject) => {
let fileReader = new FileReader()
fileReader.readAsDataURL(file)
fileReader.onload = () => resolve(fileReader.result)
fileReader.onerror = error => reject(error)
})
const setDropInfos = (name, size) => {
input.setDropInfo(
{
name: name,
size: (Math.round(size / 100 + 'e-2') / 100) + ' MB'
}
)
}
return (
<div
onDrop={event => onLoadFileDrop(event)}
className='upload_input_container'
>
<p>
{
typeof input.dropInfo === 'string' ?
input.dropInfo
:
input.dropInfo.name
}
</p>
<p>
{
typeof input.dropInfo === 'string' ?
""
:
input.dropInfo.size
}
</p>
<input
id={input.name + info.action + info.endpoint + 'Input'}
className='upload_input'
type='file'
accept={input.fileType + '/*'}
autoComplete='off'
onChange={event => onLoadFile(event)}
/>
</div>
)
}
/**
* Text input generator, example:
* @param {
* {
* type: 'range',
* name: 'name',
* min: min range value,
* max: max range value,
* step: step of value,
* unit: unit of range value,
* ref: React.createRef()
* } } input - basic text input
* @param {
* {
* type: 'info',
* action: 'Update'
* endpoint: 'Album'
* } } info - information about form
*/
const RangeInputGenerator = ({
input, info
}) => {
let name = input.name + info.action + info.endpoint + 'Input'
const [value, setValue] = useState(0)
return (
<div>
<div>
{input.name + ': ' + value + ' ' + input.unit }
</div>
<input
style={ { width: '380px' } }
id={name}
name={name}
min={input.min}
max={input.max}
defaultValue={input.min}
step={input.step}
ref={input.ref}
type='range'
onChange={ event => setValue( event.target.value ) }
/>
</div>
)
}
const RangeGenerator = ({
key,
label,
labelStyle,
valueStyle,
style,
name,
unit,
min,
max,
defaultValue,
step,
reference
}) => {
const [value, setValue] = useState(0)
return (
<div style={ { display: 'flex' } }>
<div style={ labelStyle }>
{ label + ': ' }
</div>
<input
key={key}
style={ style }
id={ name }
name={ name }
min={min}
max={max}
defaultValue={ defaultValue }
step={step}
ref={reference}
type='range'
onChange={ event => setValue( event.target.value ) }
/>
<div style={ valueStyle }>
{ value + ' ' + unit }
</div>
</div>
)
}
/**
* Text input generator, example:
* @param {
* {
* type: 'vector',
* name: 'name',
* refDict:
* {
* x: React.createRef(),
* y: React.createRef(),
* z: React.createRef()
* }
* } } input - basic text input
* @param {
* {
* type: 'info',
* action: 'Update'
* endpoint: 'Album'
* } } info - information about form
*/
const VectorInputGenerator = ({
input, info
}) => {
return (
<div style={ { width: '' } }>
<div style={ { width: '100%' } }>
{ input.name }
</div>
<div style={ { display: 'flex' } }>
{
Object.keys(input.refDict).map( (key) => {
let name = input.name + key + info.action + info.endpoint + 'Input'
return (
<div style={ { display: 'flex', width: '140px' } }>
<RangeGenerator
key={key}
label={key}
labelStyle={ { width: '5px', marginTop: '15px' } }
valueStyle={ { width: '5px', marginTop: '15px', marginLeft: '5px' } }
style={ { width: '80px' } }
name={name}
unit={ '' }
min={input.min[key]}
max={input.max[key]}
defaultValue={ input.min[key] > 0 ? input.min[key] : 0 }
step={0.1}
reference={input.refDict[key]}
/>
</div>
)
}
)
}
</div>
</div>
)
}
export default FormGenerator

View File

@ -1,308 +0,0 @@
import React, { useState, useMemo } from 'react';
/**
* Generic List Generator Component
*
* @param {Array} data - Array of items to display
* @param {string} title - Title of the list
* @param {ReactElement|Function} onCreate - Component shown when user clicks "Create +"
* @param {ReactElement|Function} onUpdate - Component shown when user clicks "Update"
* @param {Function} onDelete - Function called when user clicks "Delete"
* @param {Function} onRefresh - Optional function to refresh the list
*/
export const ListGenerator = ({
data = [],
title,
onCreate = null,
onUpdate = null,
onDelete = null,
onRefresh = null
}) => {
const columns = data.length > 0
? Object.keys(data[0]).filter(key => !key.toLowerCase().includes('id'))
: [];
const [createVisible, setCreateVisible] = useState(false);
const [itemBeingUpdated, setItemBeingUpdated] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [selectedItem, setSelectedItem] = useState(null);
const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage, setItemsPerPage] = useState(10);
const pageOptions = [5, 10, 15, 25, 50];
const totalPages = Math.ceil(data.length / itemsPerPage);
// Oblicz aktualnie wyświetlane elementy
const currentItems = useMemo(() => {
const startIndex = (currentPage - 1) * itemsPerPage;
return data.slice(startIndex, startIndex + itemsPerPage);
}, [data, currentPage, itemsPerPage]);
// Obsługa zmiany strony
const handlePageChange = (newPage) => {
setCurrentPage(newPage);
setSelectedItem(null);
};
// Obsługa zmiany liczby elementów na stronie
const handleItemsPerPageChange = (event) => {
const newItemsPerPage = parseInt(event.target.value);
setItemsPerPage(newItemsPerPage);
setCurrentPage(1);
setSelectedItem(null);
};
// Toggle the "create" form
const handleToggleCreate = () => {
setCreateVisible((prev) => !prev);
setItemBeingUpdated(null);
setSelectedItem(null);
};
// Toggle update form for a specific item
const handleToggleUpdate = (itemId) => {
setItemBeingUpdated((prev) => (prev === itemId ? null : itemId));
setCreateVisible(false);
};
// Handle delete with confirmation
const handleDelete = async (item) => {
if (window.confirm('Are you sure you want to delete this item?')) {
setIsLoading(true);
try {
if (typeof onDelete === 'function') {
await onDelete(item);
if (onRefresh) {
await onRefresh();
}
}
} catch (error) {
console.error('Error deleting item:', error);
alert('Failed to delete item. Please try again.');
} finally {
setIsLoading(false);
}
}
};
// Handle refresh
const handleRefresh = async () => {
if (onRefresh) {
setIsLoading(true);
try {
await onRefresh();
} catch (error) {
console.error('Error refreshing list:', error);
alert('Failed to refresh list. Please try again.');
} finally {
setIsLoading(false);
}
}
};
// Handle item selection
const handleItemClick = (item) => {
setSelectedItem(item);
};
// Helper to render a component if it's a function or a React element
const renderComponent = (component, props = {}) => {
if (typeof component === 'function') {
return component(props);
}
return React.cloneElement(component, props);
};
return (
<div className="list-generator-container">
<div className="table-header">
{title && <h2>{title}</h2>}
<div className="header-actions">
{onRefresh && (
<button
className="refresh-button"
onClick={handleRefresh}
disabled={isLoading}
>
{isLoading ? 'Refreshing...' : 'Refresh'}
</button>
)}
{onCreate && (
<button
className="create-button"
onClick={handleToggleCreate}
>
{createVisible ? 'Close' : `+ ${title || 'Item'}`}
</button>
)}
</div>
</div>
{createVisible && onCreate && (
<div className="create-form">
{renderComponent(onCreate)}
</div>
)}
<div className="items-columns">
{columns.map((column) => (
<div key={column} className="item-column-row">
{column.toUpperCase()}
</div>
))}
{(onUpdate || onDelete) && (
<div className="item-column-row">Actions</div>
)}
</div>
<div className="items-list">
{data.length === 0 ? (
<div className="no-data">
No items found. {onCreate && `Click '+ ${title || 'Item'}' to add new items.`}
</div>
) : (
currentItems.map((item) => (
<div
key={item.id}
className={`item-row ${selectedItem?.id === item.id ? 'selected' : ''}`}
onClick={() => handleItemClick(item)}
>
{Object.entries(item)
.filter(([key]) => !key.toLowerCase().includes('id'))
.map(([key, value], index) => (
<div key={index} className="item-info">
{key.toLowerCase() === 'progress' ? (
value === 100 ? (
<span className="completed-text">Completed</span>
) : (
<div className="progress-bar">
<div
className="progress-fill"
style={{ width: `${value}%` }}
/>
<span className="progress-text">{value}%</span>
</div>
)
) : key.toLowerCase() === 'status' ? (
<span className={`status-text ${value.toLowerCase().replace(/\s+/g, '-')}`}>
{value}
</span>
) : (
<span>{value}</span>
)}
</div>
))}
{(onUpdate || onDelete) && (
<div className="action-buttons">
{onUpdate && (
<button
className="update-button"
onClick={(e) => {
e.stopPropagation();
handleToggleUpdate(item.id);
}}
>
{itemBeingUpdated === item.id ? 'Close' : 'Update'}
</button>
)}
{onDelete && (
<button
className="delete-button"
onClick={(e) => {
e.stopPropagation();
handleDelete(item);
}}
disabled={isLoading}
>
Delete
</button>
)}
</div>
)}
{itemBeingUpdated === item.id && onUpdate && (
<div className="update-form">
{renderComponent(onUpdate, { item })}
</div>
)}
</div>
))
)}
</div>
{data.length > 0 && (
<div className="pagination-controls">
<div className="items-per-page">
<span>Items per page:</span>
<select value={itemsPerPage} onChange={handleItemsPerPageChange}>
{pageOptions.map(option => (
<option key={option} value={option}>{option}</option>
))}
</select>
</div>
<div className="pagination-buttons">
<button
onClick={() => handlePageChange(1)}
disabled={currentPage === 1}
className="pagination-button"
>
&lt;&lt;
</button>
<button
onClick={() => handlePageChange(currentPage - 1)}
disabled={currentPage === 1}
className="pagination-button"
>
&lt;
</button>
<span className="page-info">
Page {currentPage} of {totalPages}
</span>
<button
onClick={() => handlePageChange(currentPage + 1)}
disabled={currentPage === totalPages}
className="pagination-button"
>
&gt;
</button>
<button
onClick={() => handlePageChange(totalPages)}
disabled={currentPage === totalPages}
className="pagination-button"
>
&gt;&gt;
</button>
</div>
</div>
)}
<div className="element-details">
{selectedItem ? (
<div className="details-content">
<h3>Details</h3>
{Object.entries(selectedItem)
.filter(([key]) => !key.toLowerCase().includes('id'))
.map(([key, value]) => (
<div key={key} className="detail-row">
<span className="detail-label">{key}:</span>
<span className="detail-value">
{key.toLowerCase() === 'progress' ? (
value === 100 ? (
<span className="completed-text">Completed</span>
) : (
<span>{value}%</span>
)
) : (
value
)}
</span>
</div>
))}
</div>
) : (
<div className="no-selection">
Select an item to view details
</div>
)}
</div>
</div>
);
};

View File

@ -1,65 +0,0 @@
import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { userAuthSelector } from '../../../redux/slices/userAuthSlice'
import { renderCrudSelector } from '../../../redux/slices/renderCrudSlice'
import renderCrudAsyncThunk from '../../../redux/asyncThunks/renderCrudAsyncThunk'
import { GeneralAddress } from '../../../redux/asyncThunks/abstracts/abstractAddress'
import FormGenerator from '../formGenerator'
const RenderShowAndDownloadForm = () => {
const dispatch = useDispatch()
const { render_list } = useSelector( renderCrudSelector )
const { user, token } = useSelector( userAuthSelector )
let blocker = false
useEffect(
() => {
if ( render_list.length === 0 && user.id > 0 && token !== '' && !blocker ) {
dispatch( renderCrudAsyncThunk.fetchGetAllRenders( token ) )
if ( render_list.length === 0 ) {
blocker = true
}
}
}
)
let inputList = [
{
type: 'info',
action: 'Download',
endpint: 'model/download',
button_value: 'Refresh Renders List'
},
{
type: 'links-listing',
name: 'Renders',
values: render_list,
link: GeneralAddress + '/render/',
}
]
const handleRefresh = () => {
dispatch( renderCrudAsyncThunk.fetchGetAllRenders( token ) )
}
return (
<div className='float_form_render_sync'>
<FormGenerator
inputList={ inputList }
refList={ [] }
action={ handleRefresh }
/>
</div>
)
}
export default RenderShowAndDownloadForm

View File

@ -1,106 +0,0 @@
import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { userAuthSelector } from '../../../redux/slices/userAuthSlice'
import { modelCrudSelector } from '../../../redux/slices/modelCrudSlice'
import modelCrudAsyncThunk from '../../../redux/asyncThunks/modelCrudAsyncThunk'
import AbstractWebsocket from '../abstractWebsocket'
const RenderAllForm = () => {
const dispatch = useDispatch()
const choiceListing = React.createRef()
const rotateRange = React.createRef()
const resolutionXRange = React.createRef()
const resolutionYRange = React.createRef()
const { models_list } = useSelector( modelCrudSelector )
const { user, token } = useSelector( userAuthSelector )
let refList = [
choiceListing,
rotateRange,
resolutionXRange,
resolutionYRange,
]
let inputList = [
{
type: 'info',
action: 'Async',
endpint: 'render/async/all',
button_value: 'Render All Sets'
},
{
type: 'choice-listing',
name: 'Models',
values: models_list,
ref: choiceListing
},
{
type: 'range',
name: 'Rotate',
min: 1,
max: 360,
step: 1,
unit: 'deg',
ref: rotateRange
},
{
type: 'range',
name: 'Resolution X',
min: 600,
max: 4096,
step: 10,
unit: 'px',
ref: resolutionXRange
},
{
type: 'range',
name: 'Resolution Y',
min: 300,
max: 3112,
step: 10,
unit: 'px',
ref: resolutionYRange
},
]
useEffect(
() => {
if ( models_list.length === 0 && user.id > 0 && token !== '' ) {
dispatch( modelCrudAsyncThunk.fetchGetAllModels( token ) )
}
}
)
const bodyComparer = ( refs ) => {
return {
fileName: refs[0].current.value.replace('.blend', ''),
// fileName: 'testHand',
angle: refs[1].current.value / 62, // on backend 0.1 - 6.2 value
resolutionX: refs[2].current.value,
resolutionY: refs[3].current.value,
}
}
return (
<div>
<AbstractWebsocket
addressWS={ '/all/' }
inputList={ inputList }
refList={ refList }
bodyComparer={ bodyComparer }
/>
</div>
)
}
export default RenderAllForm

View File

@ -1,136 +0,0 @@
import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { userAuthSelector } from '../../../redux/slices/userAuthSlice'
import { modelCrudSelector } from '../../../redux/slices/modelCrudSlice'
import modelCrudAsyncThunk from '../../../redux/asyncThunks/modelCrudAsyncThunk'
import AbstractWebsocket from '../abstractWebsocket'
const RenderSingleImageForm = () => {
const dispatch = useDispatch()
const choiceListing = React.createRef()
const setIdRange = React.createRef()
const rotateRange = React.createRef()
const cameraIdRange = React.createRef()
const resolutionXRange = React.createRef()
const resolutionYRange = React.createRef()
const { models_list } = useSelector( modelCrudSelector )
const { user, token } = useSelector( userAuthSelector )
let refList = [
choiceListing,
setIdRange,
rotateRange,
cameraIdRange,
resolutionXRange,
resolutionYRange
]
let inputList = [
{
type: 'info',
action: 'Async',
endpint: 'render/async/single/image',
button_value: 'Render Single Image'
},
{
type: 'choice-listing',
name: 'Models',
values: models_list,
ref: choiceListing
},
{
type: 'range',
name: 'Set ID',
min: 0,
max: 87,
step: 1,
unit: 'set',
ref: setIdRange
},
{
type: 'range',
name: 'Rotate',
min: 1,
max: 360,
step: 1,
unit: 'deg',
ref: rotateRange
},
{
type: 'range',
name: 'Camera ID',
min: 0,
max: 1,
step: 1,
unit: 'camera index',
ref: cameraIdRange
},
{
type: 'range',
name: 'Resolution X',
min: 600,
max: 4096,
step: 10,
unit: 'px',
ref: resolutionXRange
},
{
type: 'range',
name: 'Resolution Y',
min: 300,
max: 3112,
step: 10,
unit: 'px',
ref: resolutionYRange
},
]
let blocker = false
useEffect(
() => {
if ( models_list.length === 0 && user.id > 0 && token !== '' && blocker === false ) {
dispatch( modelCrudAsyncThunk.fetchGetAllModels( token ) )
if ( models_list.length === 0 ) {
blocker = true
}
}
}
)
const bodyComparer = ( refs ) => {
return {
fileName: refs[0].current.value.replace('.blend', ''),
// fileName: 'testHand',
setID: refs[1].current.value,
rotate: refs[2].current.value / 62, // on backend 0.1 - 6.2 value
cameraID: refs[3].current.value,
nameSeries: 0,
resolutionX: refs[4].current.value,
resolutionY: refs[5].current.value
}
}
return (
<div>
<AbstractWebsocket
addressWS={ '/single/image/' }
inputList={ inputList }
refList={ refList }
bodyComparer={ bodyComparer }
/>
</div>
)
}
export default RenderSingleImageForm

View File

@ -1,134 +0,0 @@
import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { userAuthSelector } from '../../../redux/slices/userAuthSlice'
import { modelCrudSelector } from '../../../redux/slices/modelCrudSlice'
import modelCrudAsyncThunk from '../../../redux/asyncThunks/modelCrudAsyncThunk'
import AbstractWebsocket from '../abstractWebsocket'
const RenderSingleSetForm = () => {
const dispatch = useDispatch()
const choiceListing = React.createRef()
const setIdRange = React.createRef()
const cameraIdRange = React.createRef()
const resolutionXRange = React.createRef()
const resolutionYRange = React.createRef()
const angleRange = React.createRef()
const { models_list } = useSelector( modelCrudSelector )
const { user, token } = useSelector( userAuthSelector )
let refList = [
choiceListing,
setIdRange,
cameraIdRange,
resolutionXRange,
resolutionYRange,
angleRange
]
let inputList = [
{
type: 'info',
action: 'Async',
endpint: 'render/async/single/set',
button_value: 'Render Single Set'
},
{
type: 'choice-listing',
name: 'Models',
values: models_list,
ref: choiceListing
},
{
type: 'range',
name: 'Set ID',
min: 0,
max: 87,
step: 1,
unit: 'set',
ref: setIdRange
},
{
type: 'range',
name: 'Camera ID',
min: 0,
max: 1,
step: 1,
unit: 'camera index',
ref: cameraIdRange
},
{
type: 'range',
name: 'Resolution X',
min: 600,
max: 4096,
step: 10,
unit: 'px',
ref: resolutionXRange
},
{
type: 'range',
name: 'Resolution Y',
min: 300,
max: 3112,
step: 10,
unit: 'px',
ref: resolutionYRange
},
{
type: 'range',
name: 'Rotate',
min: 1,
max: 360,
step: 1,
unit: 'deg',
ref: angleRange
},
]
let blocker = false
useEffect(
() => {
if ( models_list.length === 0 && user.id > 0 && token !== '' && blocker === false ) {
dispatch( modelCrudAsyncThunk.fetchGetAllModels( token ) )
if ( models_list.length === 0 ) {
blocker = true
}
}
}
)
const bodyComparer = ( refs ) => {
return {
fileName: refs[0].current.value.replace('.blend', ''),
// fileName: 'testHand',
setID: refs[1].current.value,
cameraID: refs[2].current.value,
resolutionX: refs[3].current.value,
resolutionY: refs[4].current.value,
angle: refs[5].current.value / 62, // on backend 0.1 - 6.2 value
}
}
return (
<div>
<AbstractWebsocket
addressWS={ '/single/set/' }
inputList={ inputList }
refList={ refList }
bodyComparer={ bodyComparer }
/>
</div>
)
}
export default RenderSingleSetForm

View File

@ -1,445 +0,0 @@
import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { userAuthSelector } from '../../../redux/slices/userAuthSlice'
import { modelCrudSelector } from '../../../redux/slices/modelCrudSlice'
import modelCrudAsyncThunk from '../../../redux/asyncThunks/modelCrudAsyncThunk'
import AbstractWebsocket from '../abstractWebsocket'
const refVectorGenerator = () => {
return {
x: React.createRef(),
y: React.createRef(),
z: React.createRef(),
}
}
const RenderVectorSingleImageForm = () => {
const dispatch = useDispatch()
const choiceListing = React.createRef()
const rotateRange = React.createRef()
const cameraIdRange = React.createRef()
const resolutionXRange = React.createRef()
const resolutionYRange = React.createRef()
// const IK_nadgarstek = refVectorGenerator()
// const IK_joint3_R = refVectorGenerator()
// const IK_joint4_R = refVectorGenerator()
// const IK_joint5_R = refVectorGenerator()
// const IK_joint6_R = refVectorGenerator()
const IK_maly_1_R = refVectorGenerator()
const IK_maly_2_R = refVectorGenerator()
const IK_maly_3_R = refVectorGenerator()
const IK_serdeczny_1_R = refVectorGenerator()
const IK_serdeczny_2_R = refVectorGenerator()
const IK_serdeczny_3_R = refVectorGenerator()
const IK_srodkowy_1_R = refVectorGenerator()
const IK_srodkowy_2_R = refVectorGenerator()
const IK_srodkowy_3_R = refVectorGenerator()
const IK_wskazujacy_1_R = refVectorGenerator()
const IK_wskazujacy_2_R = refVectorGenerator()
const IK_wskazujacy_3_R = refVectorGenerator()
const IK_kciuk_0_R = refVectorGenerator()
const IK_kciuk_1_R = refVectorGenerator()
const IK_kciuk_2_R = refVectorGenerator()
const { models_list } = useSelector( modelCrudSelector )
const { user, token } = useSelector( userAuthSelector )
let refList = [
choiceListing,
rotateRange,
cameraIdRange,
resolutionXRange,
resolutionYRange,
{
// IK_nadgarstek: IK_nadgarstek,
// IK_joint3_R: IK_joint3_R,
// IK_joint4_R: IK_joint4_R,
// IK_joint5_R: IK_joint5_R,
// IK_joint6_R: IK_joint6_R,
IK_maly_1_R: IK_maly_1_R,
IK_maly_2_R: IK_maly_2_R,
IK_maly_3_R: IK_maly_3_R,
IK_serdeczny_1_R: IK_serdeczny_1_R,
IK_serdeczny_2_R: IK_serdeczny_2_R,
IK_serdeczny_3_R: IK_serdeczny_3_R,
IK_srodkowy_1_R: IK_srodkowy_1_R,
IK_srodkowy_2_R: IK_srodkowy_2_R,
IK_srodkowy_3_R: IK_srodkowy_3_R,
IK_wskazujacy_1_R: IK_wskazujacy_1_R,
IK_wskazujacy_2_R: IK_wskazujacy_2_R,
IK_wskazujacy_3_R: IK_wskazujacy_3_R,
IK_kciuk_0_R: IK_kciuk_0_R,
IK_kciuk_1_R: IK_kciuk_1_R,
IK_kciuk_2_R: IK_kciuk_2_R,
}
]
const fingers_max = {
x: 10,
y: 10,
z: 10
}
const fingers_min = {
x: -0.7,
y: -0.7,
z: -0.7
}
const validate_fingers = {
thumb: {
max:{
part_0: {
y: 0.5,
x: 0.5,
z: 0.6
},
part_1: {
y: 0,
x: 0,
z: 0.7,
},
part_2: {
y: 0,
x: 0,
z: 0.7,
}
},
min: {
part_0: {
y: -0.3,
x: 0,
z: -0.3,
},
part_1: {
y: -0.1,
x: 0,
z: 0,
},
part_2: {
y: 0,
x: 0,
z: -0.4,
}
}
},
others: {
max: {
part_1: {
y: 0.2,
x: 0,
z: 0.7
},
part_2: {
y: 0,
x: 0,
z: 1.6
},
part_3: {
y: 0,
x: 0,
z: 0.7
}
},
min: {
part_1: {
y: -0.3,
x: 0,
z: -0.3
},
part_2: {
y: 0,
x: 0,
z: 0
},
part_3: {
y: 0,
x: 0,
z: 0
}
}
}
}
let inputList = [
{
type: 'info',
action: 'Async',
endpint: 'render/async/single/image',
button_value: 'Render Single Image'
},
{
type: 'choice-listing',
name: 'Models',
values: models_list,
ref: choiceListing
},
{
type: 'range',
name: 'Rotate',
min: 1,
max: 360,
step: 1,
unit: 'deg',
ref: rotateRange
},
{
type: 'range',
name: 'Camera ID',
min: 0,
max: 1,
step: 1,
unit: 'camera index',
ref: cameraIdRange
},
{
type: 'range',
name: 'Resolution X',
min: 600,
max: 4096,
step: 10,
unit: 'px',
ref: resolutionXRange
},
{
type: 'range',
name: 'Resolution Y',
min: 300,
max: 3112,
step: 10,
unit: 'px',
ref: resolutionYRange
},
// {
// type: 'vector',
// name: 'Wirst (experimental)',
// native: 'Nadgarstek',
// min: fingers_min,
// max: fingers_max,
// refDict: IK_nadgarstek,
// },
// {
// type: 'vector',
// name: 'Litte Finger Joint 3 (experimental)',
// native: 'Mały Palec Joint 3',
// min: fingers_min,
// max: fingers_max,
// refDict: IK_joint3_R,
// },
// {
// type: 'vector',
// name: 'Ring Finger Joint 4 (experimental)',
// native: 'Serdeczny Palec Joint 4',
// min: fingers_min,
// max: fingers_max,
// refDict: IK_joint4_R,
// },
// {
// type: 'vector',
// name: 'Middle Finger Joint 5 (experimental)',
// native: 'Środkowy Palec Joint 5',
// min: fingers_min,
// max: fingers_max,
// refDict: IK_joint5_R,
// },
// {
// type: 'vector',
// name: 'Index Finger Joint 6 (experimental)',
// native: 'Wskazujący Palec Joint 6',
// min: fingers_min,
// max: fingers_max,
// refDict: IK_joint6_R,
// },
{
type: 'vector',
name: 'Litte Finger 1',
native: 'Mały 1',
min: validate_fingers.others.min.part_1,
max: validate_fingers.others.max.part_1,
refDict: IK_maly_1_R,
},
{
type: 'vector',
name: 'Litte Finger 2',
native: 'Mały 2',
min: validate_fingers.others.min.part_2,
max: validate_fingers.others.max.part_2,
refDict: IK_maly_2_R,
},
{
type: 'vector',
name: 'Litte Finger 3',
native: 'Mały 3',
min: validate_fingers.others.min.part_3,
max: validate_fingers.others.max.part_3,
refDict: IK_maly_3_R,
},
{
type: 'vector',
name: 'Ring Finger 1',
native: 'Serdeczny 1',
min: validate_fingers.others.min.part_1,
max: validate_fingers.others.max.part_1,
refDict: IK_serdeczny_1_R,
},
{
type: 'vector',
name: 'Ring Finger 2',
native: 'Serdeczny 2',
min: validate_fingers.others.min.part_2,
max: validate_fingers.others.max.part_2,
refDict: IK_serdeczny_2_R,
},
{
type: 'vector',
name: 'Ring Finger 3',
native: 'Serdeczny 3',
min: validate_fingers.others.min.part_3,
max: validate_fingers.others.max.part_3,
refDict: IK_serdeczny_3_R,
},
{
type: 'vector',
name: 'Middle Finger 1',
native: 'Środkowy 1',
min: validate_fingers.others.min.part_1,
max: validate_fingers.others.max.part_1,
refDict: IK_srodkowy_1_R,
},
{
type: 'vector',
name: 'Middle Finger 2',
native: 'Środkowy 2',
min: validate_fingers.others.min.part_2,
max: validate_fingers.others.max.part_2,
refDict: IK_srodkowy_2_R,
},
{
type: 'vector',
name: 'Middle Finger 3',
native: 'Środkowy 3',
min: validate_fingers.others.min.part_3,
max: validate_fingers.others.max.part_3,
refDict: IK_srodkowy_3_R,
},
{
type: 'vector',
name: 'Index Finger 1',
native: 'Wskazujący 1',
min: validate_fingers.others.min.part_1,
max: validate_fingers.others.max.part_1,
refDict: IK_wskazujacy_1_R,
},
{
type: 'vector',
name: 'Index Finger 2',
native: 'Wskazujący 2',
min: validate_fingers.others.min.part_2,
max: validate_fingers.others.max.part_2,
refDict: IK_wskazujacy_2_R,
},
{
type: 'vector',
name: 'Index Finger 3',
native: 'Wskazujący 3',
min: validate_fingers.others.min.part_3,
max: validate_fingers.others.max.part_3,
refDict: IK_wskazujacy_3_R,
},
{
type: 'vector',
name: 'Thumb 0',
native: 'Kciuk 0',
min: validate_fingers.thumb.min.part_0,
max: validate_fingers.thumb.max.part_0,
refDict: IK_kciuk_0_R,
},
{
type: 'vector',
name: 'Thumb 1',
native: 'Kciuk 1',
min: validate_fingers.thumb.min.part_1,
max: validate_fingers.thumb.max.part_1,
refDict: IK_kciuk_1_R,
},
{
type: 'vector',
name: 'Thumb 2',
native: 'Kciuk 2',
min: validate_fingers.thumb.min.part_2,
max: validate_fingers.thumb.max.part_2,
refDict: IK_kciuk_2_R,
},
]
let blocker = false
useEffect(
() => {
if ( models_list.length === 0 && user.id > 0 && token !== '' && blocker === false ) {
dispatch( modelCrudAsyncThunk.fetchGetAllModels( token ) )
if ( models_list.length === 0 ) {
blocker = true
}
}
}
)
const bodyComparer = ( refs ) => {
let vectors = {}
console.log( refs )
Object.keys(refs[5]).map(
( key ) => {
let singleFinger = {
scale: 0,
x: 0,
y: 0,
z: 0
}
singleFinger['scale'] = 0.9
singleFinger['x'] = parseFloat(refs[5][key]['x'].current.value)
singleFinger['y'] = parseFloat(refs[5][key]['y'].current.value)
singleFinger['z'] = parseFloat(refs[5][key]['z'].current.value)
vectors[key] = singleFinger
}
)
return {
fileName: refs[0].current.value.replace('.blend', ''),
// fileName: 'testHand',
rotate: refs[1].current.value / 62, // on backend 0.1 - 6.2 value
cameraID: refs[2].current.value,
nameSeries: 0,
resolutionX: refs[3].current.value,
resolutionY: refs[4].current.value,
vectors: vectors
}
}
return (
<div>
<AbstractWebsocket
addressWS={ '/vector/single/image/' }
inputList={ inputList }
refList={ refList }
bodyComparer={ bodyComparer }
/>
</div>
)
}
export default RenderVectorSingleImageForm

View File

@ -1,444 +0,0 @@
import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { userAuthSelector } from '../../../redux/slices/userAuthSlice'
import { modelCrudSelector } from '../../../redux/slices/modelCrudSlice'
import modelCrudAsyncThunk from '../../../redux/asyncThunks/modelCrudAsyncThunk'
import AbstractWebsocket from '../abstractWebsocket'
const refVectorGenerator = () => {
return {
x: React.createRef(),
y: React.createRef(),
z: React.createRef(),
}
}
const RenderVectorSingleSetForm = () => {
const dispatch = useDispatch()
const choiceListing = React.createRef()
const rotateRange = React.createRef()
const cameraIdRange = React.createRef()
const resolutionXRange = React.createRef()
const resolutionYRange = React.createRef()
// const IK_nadgarstek = refVectorGenerator()
// const IK_joint3_R = refVectorGenerator()
// const IK_joint4_R = refVectorGenerator()
// const IK_joint5_R = refVectorGenerator()
// const IK_joint6_R = refVectorGenerator()
const IK_maly_1_R = refVectorGenerator()
const IK_maly_2_R = refVectorGenerator()
const IK_maly_3_R = refVectorGenerator()
const IK_serdeczny_1_R = refVectorGenerator()
const IK_serdeczny_2_R = refVectorGenerator()
const IK_serdeczny_3_R = refVectorGenerator()
const IK_srodkowy_1_R = refVectorGenerator()
const IK_srodkowy_2_R = refVectorGenerator()
const IK_srodkowy_3_R = refVectorGenerator()
const IK_wskazujacy_1_R = refVectorGenerator()
const IK_wskazujacy_2_R = refVectorGenerator()
const IK_wskazujacy_3_R = refVectorGenerator()
const IK_kciuk_0_R = refVectorGenerator()
const IK_kciuk_1_R = refVectorGenerator()
const IK_kciuk_2_R = refVectorGenerator()
const { models_list } = useSelector( modelCrudSelector )
const { user, token } = useSelector( userAuthSelector )
let refList = [
choiceListing,
rotateRange,
cameraIdRange,
resolutionXRange,
resolutionYRange,
{
// IK_nadgarstek: IK_nadgarstek,
// IK_joint3_R: IK_joint3_R,
// IK_joint4_R: IK_joint4_R,
// IK_joint5_R: IK_joint5_R,
// IK_joint6_R: IK_joint6_R,
IK_maly_1_R: IK_maly_1_R,
IK_maly_2_R: IK_maly_2_R,
IK_maly_3_R: IK_maly_3_R,
IK_serdeczny_1_R: IK_serdeczny_1_R,
IK_serdeczny_2_R: IK_serdeczny_2_R,
IK_serdeczny_3_R: IK_serdeczny_3_R,
IK_srodkowy_1_R: IK_srodkowy_1_R,
IK_srodkowy_2_R: IK_srodkowy_2_R,
IK_srodkowy_3_R: IK_srodkowy_3_R,
IK_wskazujacy_1_R: IK_wskazujacy_1_R,
IK_wskazujacy_2_R: IK_wskazujacy_2_R,
IK_wskazujacy_3_R: IK_wskazujacy_3_R,
IK_kciuk_0_R: IK_kciuk_0_R,
IK_kciuk_1_R: IK_kciuk_1_R,
IK_kciuk_2_R: IK_kciuk_2_R,
}
]
const fingers_max = {
x: 10,
y: 10,
z: 10
}
const fingers_min = {
x: -0.7,
y: -0.7,
z: -0.7
}
const validate_fingers = {
thumb: {
max:{
part_0: {
y: 0.5,
x: 0.5,
z: 0.6
},
part_1: {
y: 0,
x: 0,
z: 0.7,
},
part_2: {
y: 0,
x: 0,
z: 0.7,
}
},
min: {
part_0: {
y: -0.3,
x: 0,
z: -0.3,
},
part_1: {
y: -0.1,
x: 0,
z: 0,
},
part_2: {
y: 0,
x: 0,
z: -0.4,
}
}
},
others: {
max: {
part_1: {
y: 0.2,
x: 0,
z: 0.7
},
part_2: {
y: 0,
x: 0,
z: 1.6
},
part_3: {
y: 0,
x: 0,
z: 0.7
}
},
min: {
part_1: {
y: -0.3,
x: 0,
z: -0.3
},
part_2: {
y: 0,
x: 0,
z: 0
},
part_3: {
y: 0,
x: 0,
z: 0
}
}
}
}
let inputList = [
{
type: 'info',
action: 'Async',
endpint: 'render/async/single/set',
button_value: 'Render Single Set'
},
{
type: 'choice-listing',
name: 'Models',
values: models_list,
ref: choiceListing
},
{
type: 'range',
name: 'Rotate',
min: 1,
max: 360,
step: 1,
unit: 'deg',
ref: rotateRange
},
{
type: 'range',
name: 'Camera ID',
min: 0,
max: 1,
step: 1,
unit: 'camera index',
ref: cameraIdRange
},
{
type: 'range',
name: 'Resolution X',
min: 600,
max: 4096,
step: 10,
unit: 'px',
ref: resolutionXRange
},
{
type: 'range',
name: 'Resolution Y',
min: 300,
max: 3112,
step: 10,
unit: 'px',
ref: resolutionYRange
},
// {
// type: 'vector',
// name: 'Wirst (experimental)',
// native: 'Nadgarstek',
// min: fingers_min,
// max: fingers_max,
// refDict: IK_nadgarstek,
// },
// {
// type: 'vector',
// name: 'Litte Finger Joint 3 (experimental)',
// native: 'Mały Palec Joint 3',
// min: fingers_min,
// max: fingers_max,
// refDict: IK_joint3_R,
// },
// {
// type: 'vector',
// name: 'Ring Finger Joint 4 (experimental)',
// native: 'Serdeczny Palec Joint 4',
// min: fingers_min,
// max: fingers_max,
// refDict: IK_joint4_R,
// },
// {
// type: 'vector',
// name: 'Middle Finger Joint 5 (experimental)',
// native: 'Środkowy Palec Joint 5',
// min: fingers_min,
// max: fingers_max,
// refDict: IK_joint5_R,
// },
// {
// type: 'vector',
// name: 'Index Finger Joint 6 (experimental)',
// native: 'Wskazujący Palec Joint 6',
// min: fingers_min,
// max: fingers_max,
// refDict: IK_joint6_R,
// },
{
type: 'vector',
name: 'Litte Finger 1',
native: 'Mały 1',
min: validate_fingers.others.min.part_1,
max: validate_fingers.others.max.part_1,
refDict: IK_maly_1_R,
},
{
type: 'vector',
name: 'Litte Finger 2',
native: 'Mały 2',
min: validate_fingers.others.min.part_2,
max: validate_fingers.others.max.part_2,
refDict: IK_maly_2_R,
},
{
type: 'vector',
name: 'Litte Finger 3',
native: 'Mały 3',
min: validate_fingers.others.min.part_3,
max: validate_fingers.others.max.part_3,
refDict: IK_maly_3_R,
},
{
type: 'vector',
name: 'Ring Finger 1',
native: 'Serdeczny 1',
min: validate_fingers.others.min.part_1,
max: validate_fingers.others.max.part_1,
refDict: IK_serdeczny_1_R,
},
{
type: 'vector',
name: 'Ring Finger 2',
native: 'Serdeczny 2',
min: validate_fingers.others.min.part_2,
max: validate_fingers.others.max.part_2,
refDict: IK_serdeczny_2_R,
},
{
type: 'vector',
name: 'Ring Finger 3',
native: 'Serdeczny 3',
min: validate_fingers.others.min.part_3,
max: validate_fingers.others.max.part_3,
refDict: IK_serdeczny_3_R,
},
{
type: 'vector',
name: 'Middle Finger 1',
native: 'Środkowy 1',
min: validate_fingers.others.min.part_1,
max: validate_fingers.others.max.part_1,
refDict: IK_srodkowy_1_R,
},
{
type: 'vector',
name: 'Middle Finger 2',
native: 'Środkowy 2',
min: validate_fingers.others.min.part_2,
max: validate_fingers.others.max.part_2,
refDict: IK_srodkowy_2_R,
},
{
type: 'vector',
name: 'Middle Finger 3',
native: 'Środkowy 3',
min: validate_fingers.others.min.part_3,
max: validate_fingers.others.max.part_3,
refDict: IK_srodkowy_3_R,
},
{
type: 'vector',
name: 'Index Finger 1',
native: 'Wskazujący 1',
min: validate_fingers.others.min.part_1,
max: validate_fingers.others.max.part_1,
refDict: IK_wskazujacy_1_R,
},
{
type: 'vector',
name: 'Index Finger 2',
native: 'Wskazujący 2',
min: validate_fingers.others.min.part_2,
max: validate_fingers.others.max.part_2,
refDict: IK_wskazujacy_2_R,
},
{
type: 'vector',
name: 'Index Finger 3',
native: 'Wskazujący 3',
min: validate_fingers.others.min.part_3,
max: validate_fingers.others.max.part_3,
refDict: IK_wskazujacy_3_R,
},
{
type: 'vector',
name: 'Thumb 0',
native: 'Kciuk 0',
min: validate_fingers.thumb.min.part_0,
max: validate_fingers.thumb.max.part_0,
refDict: IK_kciuk_0_R,
},
{
type: 'vector',
name: 'Thumb 1',
native: 'Kciuk 1',
min: validate_fingers.thumb.min.part_1,
max: validate_fingers.thumb.max.part_1,
refDict: IK_kciuk_1_R,
},
{
type: 'vector',
name: 'Thumb 2',
native: 'Kciuk 2',
min: validate_fingers.thumb.min.part_2,
max: validate_fingers.thumb.max.part_2,
refDict: IK_kciuk_2_R,
},
]
let blocker = false
useEffect(
() => {
if ( models_list.length === 0 && user.id > 0 && token !== '' && blocker === false ) {
dispatch( modelCrudAsyncThunk.fetchGetAllModels( token ) )
if ( models_list.length === 0 ) {
blocker = true
}
}
}
)
const bodyComparer = ( refs ) => {
let vectors = {}
console.log( refs )
Object.keys(refs[5]).map(
( key ) => {
let singleFinger = {
scale: 0,
x: 0,
y: 0,
z: 0
}
singleFinger['scale'] = 0.9
singleFinger['x'] = parseFloat(refs[5][key]['x'].current.value)
singleFinger['y'] = parseFloat(refs[5][key]['y'].current.value)
singleFinger['z'] = parseFloat(refs[5][key]['z'].current.value)
vectors[key] = singleFinger
}
)
return {
fileName: refs[0].current.value.replace('.blend', ''),
// fileName: 'testHand',
angle: refs[1].current.value / 62, // on backend 0.1 - 6.2 value
cameraID: refs[2].current.value,
resolutionX: refs[3].current.value,
resolutionY: refs[4].current.value,
vectors: vectors
}
}
return (
<div>
<AbstractWebsocket
addressWS={ '/vector/single/set/' }
inputList={ inputList }
refList={ refList }
bodyComparer={ bodyComparer }
/>
</div>
)
}
export default RenderVectorSingleSetForm

View File

@ -1,106 +0,0 @@
import React, { useState, createRef, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { navigate } from 'gatsby';
import { loginUser } from '../../../redux/asyncThunks/userAuthAsyncThunk';
import { selectAuthError, selectAuthLoading, setError } from '../../../redux/slices/userAuthSlice';
import FormGenerator from '../formGenerator';
const UserLogin = () => {
const dispatch = useDispatch();
const error = useSelector(selectAuthError);
const loading = useSelector(selectAuthLoading);
const [infoMessage, setInfoMessage] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const usernameInput = createRef();
const passwordInput = createRef();
const [usernameValidationInfo, setUsernameValidationInfo] = useState("Empty");
const [passwordValidationInfo, setPasswordValidationInfo] = useState("Empty");
const [allowButtonAction, setAllowButtonAction] = useState(false);
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,24}$/;
const usernameValidation = (event) => {
if (event.target.value === "") {
setUsernameValidationInfo("Login jest wymagany");
} else {
setUsernameValidationInfo("Success");
}
};
const passwordValidation = (event) => {
if (event.target.value === "") {
setPasswordValidationInfo("Hasło jest wymagane");
} else if (!passwordRegex.test(event.target.value)) {
setPasswordValidationInfo("Hasło nie spełnia wymagań tej witryny");
} else {
setPasswordValidationInfo("Success");
}
};
useEffect(() => {
setAllowButtonAction(
usernameValidationInfo === "Success" &&
passwordValidationInfo === "Success"
);
}, [
usernameValidationInfo,
passwordValidationInfo,
]);
const inputList = [
{
type: 'info',
action: 'Login',
endpoint: 'auth',
button_value: loading ? 'LOGOWANIE...' : 'ZALOGUJ',
allowButtonAction: allowButtonAction
},
{
type: 'text',
name: 'LOGIN',
ref: usernameInput,
onChange: usernameValidation,
validationInfo: usernameValidationInfo
},
{
type: 'password',
name: 'HASŁO',
ref: passwordInput,
onChange: passwordValidation,
validationInfo: passwordValidationInfo
}
];
const login = async (formData) => {
try {
const credentials = {
username: formData.LOGIN,
password: formData.HASŁO
};
await dispatch(loginUser(credentials)).unwrap();
setInfoMessage("Logowanie zakończone sukcesem!");
navigate('/dashboard');
} catch (error) {
setErrorMessage("Wystąpił błąd podczas logowania (" + error.message + ")");
}
};
return (
<div className='form-container'>
<FormGenerator
inputList={inputList}
action={login}
/>
<div className='form_info'>
{infoMessage && <div className="success-message">{infoMessage}</div>}
{errorMessage && <div className="error-message">{errorMessage}</div>}
</div>
</div>
);
};
export default UserLogin;

View File

@ -1,161 +0,0 @@
import React, { useState, useEffect, createRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { navigate } from 'gatsby';
import { registerUser } from '../../../redux/asyncThunks/userAuthAsyncThunk';
import { selectAuthError, selectAuthLoading } from '../../../redux/slices/userAuthSlice';
import FormGenerator from '../formGenerator';
const UserRegister = () => {
const dispatch = useDispatch();
const error = useSelector(selectAuthError);
const loading = useSelector(selectAuthLoading);
const [infoMessage, setInfoMessage] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const usernameInput = createRef();
const emailInput = createRef();
const passwordInput = createRef();
const confirmPasswordInput = createRef();
const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,24}$/;
const [usernameValidationInfo, setUsernameValidationInfo] = useState("Empty");
const [emailValidationInfo, setEmailValidationInfo] = useState("Empty");
const [passwordValidationInfo, setPasswordValidationInfo] = useState("Empty");
const [confirmPasswordValidationInfo, setConfirmPasswordValidationInfo] = useState("Empty");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [allowButtonAction, setAllowButtonAction] = useState(false);
const usernameValidation = (event) => {
if (event.target.value === "") {
setUsernameValidationInfo("Login jest wymagany");
} else {
setUsernameValidationInfo("Success");
}
};
const emailValidation = (event) => {
if (event.target.value === "") {
setEmailValidationInfo("Email jest wymagany");
} else if (!emailRegex.test(event.target.value)) {
setEmailValidationInfo("Nieprawidłowy format emaila");
} else {
setEmailValidationInfo("Success");
}
};
const passwordValidation = (event) => {
setPassword(event.target.value);
if (event.target.value === "") {
setPasswordValidationInfo("Hasło jest wymagane");
} else if (!passwordRegex.test(event.target.value)) {
setPasswordValidationInfo("Hasło musi zawierać:\n - Minimum 8 znaków\n - Maksimum 24 znaki\n - Minimum jedną wielką literę\n - Minimum jedną małą literę\n - Minimum jedną cyfrę\n - Minimum jeden znak specjalny");
} else {
setPasswordValidationInfo("Success");
}
if (event.target.value !== confirmPassword) {
setConfirmPasswordValidationInfo("Hasła nie są identyczne");
} else {
setConfirmPasswordValidationInfo("Success");
}
};
const confirmPasswordValidation = (event) => {
setConfirmPassword(event.target.value);
if (event.target.value !== password) {
setConfirmPasswordValidationInfo("Hasła nie są identyczne");
} else {
setConfirmPasswordValidationInfo("Success");
}
};
useEffect(() => {
setAllowButtonAction(
usernameValidationInfo === "Success" &&
emailValidationInfo === "Success" &&
passwordValidationInfo === "Success" &&
confirmPasswordValidationInfo === "Success"
);
}, [
usernameValidationInfo,
emailValidationInfo,
passwordValidationInfo,
confirmPasswordValidationInfo
]);
const inputList = [
{
type: 'info',
action: 'Register',
endpoint: 'auth',
button_value: loading ? 'REJESTRACJA...' : 'ZAREJESTRUJ',
allowButtonAction: allowButtonAction
},
{
type: 'text',
name: 'LOGIN',
ref: usernameInput,
onChange: usernameValidation,
validationInfo: usernameValidationInfo
},
{
type: 'text',
name: 'EMAIL',
ref: emailInput,
onChange: emailValidation,
validationInfo: emailValidationInfo
},
{
type: 'password',
name: 'HASŁO',
ref: passwordInput,
onChange: passwordValidation,
validationInfo: passwordValidationInfo
},
{
type: 'password',
name: 'POTWIERDŹ HASŁO',
ref: confirmPasswordInput,
onChange: confirmPasswordValidation,
validationInfo: confirmPasswordValidationInfo
}
];
const register = async (formData) => {
try {
const userData = {
username: formData.LOGIN,
email: formData.EMAIL,
password: formData.HASŁO
};
await dispatch(registerUser(userData)).unwrap();
setInfoMessage("Rejestracja zakończona sukcesem!");
navigate('/dashboard');
} catch (error) {
setErrorMessage("Wystąpił błąd podczas rejestracji (" + error.massage + ")");
}
};
return (
<div className='form-container'>
<FormGenerator
inputList={inputList}
action={register}
/>
<div className='form_info'>
{infoMessage && <div className="success-message">{infoMessage}</div>}
{errorMessage && <div className="error-message">{errorMessage}</div>}
</div>
</div>
);
};
export default UserRegister;

View File

@ -1,77 +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 { deleteUser } from '../../../redux/slices/userAuthSlice'
import userCrudAsyncThunk from '../../../redux/asyncThunks/userCrudAsyncThunk'
import FormGenerator from '../formGenerator'
const UserDeleteForm = () => {
const usernameInput = React.createRef()
const { user, token } = useSelector( userAuthSelector )
const dispatch = useDispatch()
const { info } = useSelector( userCrudSelector )
let refList = [
usernameInput,
]
let inputList = [
{
type: 'info',
action: 'Create',
endpint: 'user/crud/delete',
button_value: 'Delete'
},
{
type: 'text',
name: 'Username',
ref: usernameInput
}
]
const handleDelete = async ( refs ) => {
if ( refs[0].current.value === user.username ) {
let pass = {
token: token,
user_id: user.id
}
dispatch(
deleteUser()
)
dispatch(
userCrudAsyncThunk.fetchDeleteUser(
pass
)
)
}
}
return (
<div
className="float_form_model"
style={ { marginTop: '17%'} }
>
<FormGenerator
inputList={ inputList }
refList={ refList }
action={ handleDelete }
/>
<div className='form_info'>
{ info }
</div>
</div>
)
}
export default UserDeleteForm

View File

@ -1,87 +0,0 @@
import React, { useState, useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { userCrudSelector } from '../../../redux/slices/userCrudSlice'
import { userAuthSelector } from '../../../redux/slices/userAuthSlice'
import userCrudAsyncThunk from '../../../redux/asyncThunks/userCrudAsyncThunk'
import FormGenerator from '../formGenerator'
const UserUpdateForm = () => {
const usernameInput = React.createRef()
const passwordInput = React.createRef()
const emailInput = React.createRef()
const dispatch = useDispatch()
const { info } = useSelector( userCrudSelector )
const { user, token } = useSelector( userAuthSelector )
let refList = [
usernameInput,
passwordInput,
emailInput
]
let inputList = [
{
type: 'info',
action: 'Create',
endpint: 'user/crud/update',
button_value: 'Update User'
},
{
type: 'text',
name: 'Username',
ref: usernameInput
},
{
type: 'password',
name: 'Password',
ref: passwordInput
},
{
type: 'text',
name: 'Email',
ref: emailInput
}
]
const update = async ( refs ) => {
let pass = {
user_id: user.id,
token: token,
user: {
username: refs[0].current.value,
password: refs[1].current.value,
email: refs[2].current.value,
}
}
dispatch(
userCrudAsyncThunk.fetchUpdateUser(
pass
)
)
}
return (
<div
className="float_form_model"
style={ { marginTop: '10%'} }
>
<FormGenerator
inputList={ inputList }
refList={ refList }
action={ update }
/>
<div className='form_info'>
{ info }
</div>
</div>
)
}
export default UserUpdateForm

View File

@ -1,137 +0,0 @@
import React, { useState, createRef, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { changePassword } from '../../../redux/asyncThunks/userAuthAsyncThunk';
import { selectAuthError, selectAuthLoading } from '../../../redux/slices/userAuthSlice';
import FormGenerator from '../formGenerator';
const UserChangePasswordForm = () => {
const dispatch = useDispatch();
const loading = useSelector(selectAuthLoading);
const error = useSelector(selectAuthError);
const [infoMessage, setInfoMessage] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const currentPasswordInput = createRef();
const newPasswordInput = createRef();
const confirmPasswordInput = createRef();
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,24}$/;
const [currentPasswordValidationInfo, setCurrentPasswordValidationInfo] = useState("Empty");
const [newPasswordValidationInfo, setNewPasswordValidationInfo] = useState("Empty");
const [confirmPasswordValidationInfo, setConfirmPasswordValidationInfo] = useState("Empty");
const [newPassword, setNewPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [allowButtonAction, setAllowButtonAction] = useState(false);
const currentPasswordValidation = (event) => {
if (event.target.value === "") {
setCurrentPasswordValidationInfo("Hasło jest wymagane");
} else if (event.target.value === newPassword) {
setCurrentPasswordValidationInfo("Nowe hasło nie może być takie samo jak aktualne");
} else {
setCurrentPasswordValidationInfo("Success");
}
};
const newPasswordValidation = (event) => {
setNewPassword(event.target.value);
if (event.target.value === "") {
setNewPasswordValidationInfo("Hasło jest wymagane");
} else if (!passwordRegex.test(event.target.value)) {
setNewPasswordValidationInfo("Hasło musi zawierać:\n - Minimum 8 znaków\n - Maksimum 24 znaki\n - Minimum jedną wielką literę\n - Minimum jedną małą literę\n - Minimum jedną cyfrę\n - Minimum jeden znak specjalny");
} else {
setNewPasswordValidationInfo("Success");
}
if (event.target.value !== confirmPassword) {
setConfirmPasswordValidationInfo("Hasła nie są identyczne");
} else {
setConfirmPasswordValidationInfo("Success");
}
};
const confirmPasswordValidation = (event) => {
setConfirmPassword(event.target.value);
if (event.target.value !== newPassword) {
setConfirmPasswordValidationInfo("Hasła nie są identyczne");
} else {
setConfirmPasswordValidationInfo("Success");
}
};
useEffect(() => {
setAllowButtonAction(
currentPasswordValidationInfo === "Success" &&
newPasswordValidationInfo === "Success" &&
confirmPasswordValidationInfo === "Success"
);
}, [
currentPasswordValidationInfo,
newPasswordValidationInfo,
confirmPasswordValidationInfo
]);
const inputList = [
{
type: 'info',
action: 'Update',
endpoint: 'User',
button_value: loading ? 'AKTUALIZACJA...' : 'AKTUALIZUJ',
allowButtonAction: allowButtonAction
},
{
type: 'password',
name: 'AKTUALNE HASŁO',
ref: currentPasswordInput,
onChange: currentPasswordValidation,
validationInfo: currentPasswordValidationInfo
},
{
type: 'password',
name: 'NOWE HASŁO',
ref: newPasswordInput,
onChange: newPasswordValidation,
validationInfo: newPasswordValidationInfo
},
{
type: 'password',
name: 'POTWIERDŹ NOWE HASŁO',
ref: confirmPasswordInput,
onChange: confirmPasswordValidation,
validationInfo: confirmPasswordValidationInfo
}
];
const update = async (formData) => {
try {
const userData = {
currentPassword: formData['AKTUALNE HASŁO'],
newPassword: formData['NOWE HASŁO']
};
await dispatch(changePassword(userData)).unwrap();
setInfoMessage("Hasło zostało zmienione!");
} catch (error) {
setErrorMessage("Wystąpił błąd podczas zmiany hasła (" + error.message + ")");
}
};
return (
<div className='form-container'>
<FormGenerator
inputList={inputList}
action={update}
/>
<div className='form_info'>
{infoMessage && <div className="success-message">{infoMessage}</div>}
{errorMessage && <div className="error-message">{errorMessage}</div>}
</div>
</div>
);
};
export default UserChangePasswordForm;

View File

@ -1,81 +0,0 @@
import React, { useState, createRef, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { navigate } from 'gatsby';
import { deleteAccount } from '../../../redux/asyncThunks/userAuthAsyncThunk';
import { selectAuthError, selectAuthLoading } from '../../../redux/slices/userAuthSlice';
import FormGenerator from '../formGenerator';
const UserDeleteAccountForm = () => {
const dispatch = useDispatch();
const loading = useSelector(selectAuthLoading);
const error = useSelector(selectAuthError);
const [infoMessage, setInfoMessage] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const deleteConfirmationInput = createRef();
const [deleteConfirmationValidationInfo, setDeleteConfirmationValidationInfo] = useState("Empty");
const [allowButtonAction, setAllowButtonAction] = useState(false);
const deleteConfirmationValidation = (event) => {
if (event.target.value === "") {
setDeleteConfirmationValidationInfo("Wpisz 'DELETE' aby potwierdzić usunięcie konta");
} else if (event.target.value !== "DELETE") {
setDeleteConfirmationValidationInfo("Wpisz dokładnie 'DELETE' aby potwierdzić usunięcie konta");
} else {
setDeleteConfirmationValidationInfo("Success");
}
};
useEffect(() => {
setAllowButtonAction(deleteConfirmationValidationInfo === "Success");
}, [deleteConfirmationValidationInfo]);
const inputList = [
{
type: 'info',
action: 'Delete',
endpoint: 'User',
button_value: loading ? 'USUWANIE...' : 'USUŃ KONTO',
allowButtonAction: allowButtonAction
},
{
type: 'text',
name: 'POTWIERDŹ USUNIĘCIE',
ref: deleteConfirmationInput,
onChange: deleteConfirmationValidation,
validationInfo: deleteConfirmationValidationInfo,
placeholder: "Wpisz 'DELETE' aby potwierdzić usunięcie konta"
}
];
const deleteAccountHandler = async (formData) => {
try {
if (formData['POTWIERDŹ USUNIĘCIE'] === 'DELETE') {
await dispatch(deleteAccount()).unwrap();
setInfoMessage("Konto zostało usunięte!");
setTimeout(() => {
navigate('/');
}, 2000);
} else {
setErrorMessage("Wpisz 'DELETE' aby potwierdzić usunięcie konta");
}
} catch (error) {
setErrorMessage("Wystąpił błąd podczas usuwania konta (" + error.message + ")");
}
};
return (
<div className='form-container'>
<FormGenerator
inputList={inputList}
action={deleteAccountHandler}
/>
<div className='form_info'>
{infoMessage && <div className="success-message">{infoMessage}</div>}
{errorMessage && <div className="error-message">{errorMessage}</div>}
</div>
</div>
);
};
export default UserDeleteAccountForm;

View File

@ -1,84 +0,0 @@
import React, { useState, createRef, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { updateProfile } from '../../../redux/asyncThunks/userAuthAsyncThunk';
import { selectAuthError, selectAuthLoading, selectCurrentUser } from '../../../redux/slices/userAuthSlice';
import FormGenerator from '../formGenerator';
const UserUpdateProfileForm = () => {
const dispatch = useDispatch();
const user = useSelector(selectCurrentUser);
const loading = useSelector(selectAuthLoading);
const error = useSelector(selectAuthError);
const [infoMessage, setInfoMessage] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const emailInput = createRef();
const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const [emailValidationInfo, setEmailValidationInfo] = useState("Empty");
const [allowButtonAction, setAllowButtonAction] = useState(false);
const emailValidation = (event) => {
if (event.target.value === "") {
setEmailValidationInfo("Email jest wymagany");
} else if (!emailRegex.test(event.target.value)) {
setEmailValidationInfo("Nieprawidłowy format emaila");
} else {
setEmailValidationInfo("Success");
}
};
useEffect(() => {
setAllowButtonAction(emailValidationInfo === "Success");
}, [emailValidationInfo]);
const inputList = [
{
type: 'info',
action: 'Update',
endpoint: 'User',
button_value: loading ? 'AKTUALIZACJA...' : 'AKTUALIZUJ',
allowButtonAction: allowButtonAction
},
{
type: 'label',
name: 'LOGIN',
value: user?.login || ''
},
{
type: 'text',
name: 'EMAIL',
ref: emailInput,
onChange: emailValidation,
validationInfo: emailValidationInfo,
value: user?.email || ''
}
];
const update = async (formData) => {
try {
const userData = {
email: formData.EMAIL
};
await dispatch(updateProfile(userData)).unwrap();
setInfoMessage("Profil został zaktualizowany!");
} catch (error) {
setErrorMessage("Wystąpił błąd podczas aktualizacji (" + error.message + ")");
}
};
return (
<div className='form-container'>
<FormGenerator
inputList={inputList}
action={update}
/>
<div className='form_info'>
{infoMessage && <div className="success-message">{infoMessage}</div>}
{errorMessage && <div className="error-message">{errorMessage}</div>}
</div>
</div>
);
};
export default UserUpdateProfileForm;

View File

@ -1,22 +0,0 @@
import React from 'react';
import '../styles/large.cube.scss';
const LargeCubeComponent = () => {
return (
<div className="large-graphic-container">
<div className="large-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>
)
}
export default LargeCubeComponent

View File

@ -1,28 +0,0 @@
import React from 'react';
import '../styles/general.scss';
import SmallCubeComponent from './smallCube.js';
const NavBarComponent = () => {
return (
<div className="navbar">
<div className="content-container">
<div className="content">
<div className="section">
<SmallCubeComponent />
</div>
</div>
{/* <div className="content">
<div className="section">
<h4>Menu |||</h4>
</div>
</div> */}
</div>
</div>
)
}
export default NavBarComponent

View File

@ -1,25 +0,0 @@
import React from 'react';
import '../styles/small.cube.scss';
const SmallCubeComponent = () => {
return (
<div className="graphic-container">
<div className="cube">
<div className="face-front"></div>
<div className="face-back"></div>
<div className="face-right"></div>
<div className="face-left"></div>
<div className="face-top"></div>
<div className="face-bottom"></div>
</div>
<div className="title">
XGPU
</div>
</div>
)
}
export default SmallCubeComponent

View File

@ -1,20 +0,0 @@
// Konfiguracja API
export const API_URL = process.env.REACT_APP_API_URL || 'http://localhost:3001/api';
// Konfiguracja aplikacji
export const APP_CONFIG = {
name: 'Render App',
version: '1.0.0',
environment: process.env.NODE_ENV || 'development'
};
// Konfiguracja autentykacji
export const AUTH_CONFIG = {
tokenExpiry: 7, // dni
refreshTokenExpiry: 30, // dni
cookieOptions: {
secure: true,
sameSite: 'strict',
path: '/'
}
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -1,27 +0,0 @@
// import React from 'react';
//
// import LoginPage from './pages/user/login.js';
// import LandingPage from './pages/Landing.js';
//
// const IndexPage = () => {
// return (
// <LandingPage />
// )
// }
//
//
// export default IndexPage
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);

View File

@ -1,20 +1,54 @@
import React from 'react';
import { Link } from 'react-router-dom';
import '../styles/general.scss';
import * as React from "react"
import { Link } from "gatsby"
// styles
const pageStyles = {
color: "#232129",
padding: "96px",
fontFamily: "-apple-system, Roboto, sans-serif, serif",
}
const headingStyles = {
marginTop: 0,
marginBottom: 64,
maxWidth: 320,
}
const paragraphStyles = {
marginBottom: 48,
}
const codeStyles = {
color: "#8A6534",
padding: 4,
backgroundColor: "#FFF4DB",
fontSize: "1.25rem",
borderRadius: 4,
}
// markup
const NotFoundPage = () => {
return (
<div className="landing-container">
<div className="landing">
<h1>404</h1>
<h2>Strona nie została znaleziona</h2>
<p>Przepraszamy, ale strona, której szukasz, nie istnieje.</p>
<Link to="/">
<button>Powrót do strony głównej</button>
</Link>
</div>
</div>
);
};
return (
<main style={pageStyles}>
<title>Not found</title>
<h1 style={headingStyles}>Page not found</h1>
<p style={paragraphStyles}>
Sorry{" "}
<span role="img" aria-label="Pensive emoji">
😔
</span>{" "}
we couldnt find what you were looking for.
<br />
{process.env.NODE_ENV === "development" ? (
<>
<br />
Try creating a page in <code style={codeStyles}>src/pages/</code>.
<br />
</>
) : null}
<br />
<Link to="/">Go home</Link>.
</p>
</main>
)
}
export default NotFoundPage;
export default NotFoundPage

View File

@ -1,70 +0,0 @@
import React, { useEffect, useState } from 'react';
import { getAiTasks, createAiTask, updateAiTask, deleteAiTask } from '../services/task.service';
function FormAi() {
const [tasks, setTasks] = useState([]);
const fetchTasks = async () => {
try {
const data = await getAiTasks();
setTasks(data || []);
} catch (err) {
console.error(err);
alert('Failed to load AI tasks');
}
};
useEffect(() => {
fetchTasks();
}, []);
const handleCreate = async () => {
const userId = 123; // Example user ID
try {
await createAiTask(userId);
alert('AI task created');
fetchTasks();
} catch (err) {
console.error(err);
alert('Failed to create AI task');
}
};
const handleStop = async (taskId) => {
try {
await updateAiTask(taskId, 'stop');
fetchTasks();
} catch (err) {
console.error(err);
alert('Failed to stop AI task');
}
};
const handleDelete = async (taskId) => {
try {
await deleteAiTask(taskId);
fetchTasks();
} catch (err) {
console.error(err);
alert('Failed to delete AI task');
}
};
return (
<div style={{ margin: '1rem' }}>
<h2>AI Tasks</h2>
<button onClick={handleCreate}>Create AI Task</button>
<ul>
{tasks.map((t) => (
<li key={t._id}>
Task ID: {t._id}, Status: {t.status}&nbsp;
<button onClick={() => handleStop(t._id)}>Stop</button>
<button onClick={() => handleDelete(t._id)}>Delete</button>
</li>
))}
</ul>
</div>
);
}
export default FormAi;

View File

@ -1,52 +0,0 @@
import React, { useState } from 'react';
import authService from '../services/auth.service';
import { useNavigate } from 'react-router-dom';
function FormLogin() {
const navigate = useNavigate();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleLogin = async (e) => {
e.preventDefault();
try {
await authService.login(username, password);
alert('Login successful!');
navigate('/models');
} catch (err) {
alert('Login failed');
console.error(err);
}
};
return (
<div style={{ maxWidth: '400px', margin: '0 auto' }}>
<h2>Login</h2>
<form onSubmit={handleLogin}>
<div>
<label>Username:</label>
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
required
/>
</div>
<div>
<label>Password:</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</div>
<button type="submit">Login</button>
</form>
</div>
);
}
export default FormLogin;

View File

@ -1,79 +0,0 @@
import React, { useEffect, useState } from 'react';
import { getModels, createModel, deleteModel } from '../services/model.service';
function FormModels() {
const [models, setModels] = useState([]);
const [modelName, setModelName] = useState('');
const [file, setFile] = useState(null);
const fetchModels = async () => {
try {
const data = await getModels();
setModels(data.items || []);
} catch (error) {
console.error(error);
alert('Failed to load models');
}
};
useEffect(() => {
fetchModels();
}, []);
const handleCreateModel = async (e) => {
e.preventDefault();
if (!modelName || !file) {
alert('Please provide name and file');
return;
}
try {
await createModel(modelName, file);
setModelName('');
setFile(null);
alert('Model created successfully');
fetchModels();
} catch (err) {
console.error(err);
alert('Failed to create model');
}
};
const handleDelete = async (id) => {
if (!window.confirm('Are you sure?')) return;
try {
await deleteModel(id);
fetchModels();
} catch (error) {
console.error(error);
alert('Error deleting model');
}
};
return (
<div style={{ margin: '1rem' }}>
<h2>Models</h2>
<form onSubmit={handleCreateModel}>
<input
type="text"
placeholder="Model Name"
value={modelName}
onChange={(e) => setModelName(e.target.value)}
/>
<input type="file" onChange={(e) => setFile(e.target.files?.[0] || null)} />
<button type="submit">Create Model</button>
</form>
<ul>
{models.map((m) => (
<li key={m.id}>
{m.name} (ID: {m.id}){' '}
<button onClick={() => handleDelete(m.id)}>Delete</button>
</li>
))}
</ul>
</div>
);
}
export default FormModels;

View File

@ -1,63 +0,0 @@
import React, { useState } from 'react';
import authService from '../services/auth.service';
import { useNavigate } from 'react-router-dom';
function FormRegister() {
const navigate = useNavigate();
const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleRegister = async (e) => {
e.preventDefault();
try {
await authService.register(username, password, email);
alert('Registration successful!');
navigate('/login');
} catch (err) {
alert('Registration failed');
console.error(err);
}
};
return (
<div style={{ maxWidth: '400px', margin: '0 auto' }}>
<h2>Register</h2>
<form onSubmit={handleRegister}>
<div>
<label>Username:</label>
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
required
/>
</div>
<div>
<label>Email:</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div>
<label>Password:</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</div>
<button type="submit">Register</button>
</form>
</div>
);
}
export default FormRegister;

View File

@ -1,47 +0,0 @@
import React, { useEffect, useState } from 'react';
import api from '../services/api'; // or a dedicated function
function FormRenders() {
const [renders, setRenders] = useState([]);
const fetchRenders = async () => {
try {
// GET /renders? (Your backend might differ.)
// Must handle pagination if needed
const res = await api.get('/renders', { params: { page: 1, limit: 10 } });
setRenders(res.data.items || []);
} catch (error) {
console.error(error);
alert('Failed to load renders');
}
};
useEffect(() => {
fetchRenders();
}, []);
const handleDownload = (s3Key) => {
// If the backend returns a direct S3 link, just open it:
// window.open(downloadUrl, '_blank');
// Otherwise, if you only have s3Key, you might need to build the S3 URL or call a backend endpoint that redirects.
const s3Url = `https://YOUR_BUCKET.s3.amazonaws.com/${s3Key}`;
window.open(s3Url, '_blank');
};
return (
<div style={{ margin: '1rem' }}>
<h2>Renders</h2>
{renders.map((r) => (
<div key={r.id} style={{ marginBottom: '0.5rem' }}>
<strong>{r.name}</strong> (ID: {r.id}) &nbsp;
{r.s3Key && (
<button onClick={() => handleDownload(r.s3Key)}>Download ZIP</button>
)}
</div>
))}
</div>
);
}
export default FormRenders;

View File

@ -1,32 +0,0 @@
import React from 'react';
import '../../styles/general.scss';
import LargeCubeComponent from '../../components/largeCube.js';
import UserLoginForm from '../../components/forms/user_auth/userLogin.js';
import FootComponent from '../../components/foot.js';
import NavBarComponent from '../../components/navbar.js';
const LoginPage = () => {
return (
<>
<NavBarComponent />
<div className="login-container" style={{"display": "flex"}}>
<main className="main-content">
<div style={{"padding-left": "200px"}}>
<UserLoginForm />
</div>
</main>
<main className="main-content">
<div style={{"padding-right": "200px"}}>
<LargeCubeComponent />
</div>
</main>
</div>
<FootComponent />
</>
)
}
export default LoginPage

View File

@ -1,32 +0,0 @@
import React from 'react';
import '../../styles/general.scss';
import LargeCubeComponent from '../../components/largeCube.js';
import UserRegisterForm from '../../components/forms/user_auth/userRegister.js';
import FootComponent from '../../components/foot.js';
import NavBarComponent from '../../components/navbar.js';
const RegisterPage = () => {
return (
<>
<NavBarComponent />
<div className="register-container" style={{"display": "flex"}}>
<main className="main-content">
<div style={{"padding-left": "200px"}}>
<UserRegisterForm />
</div>
</main>
<main className="main-content">
<div style={{"padding-right": "200px"}}>
<LargeCubeComponent />
</div>
</main>
</div>
<FootComponent />
</>
)
}
export default RegisterPage

View File

@ -1,142 +0,0 @@
import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { navigate } from 'gatsby';
import { logoutUser, checkAuth } from '../redux/asyncThunks/userAuthAsyncThunk';
import { selectIsAuthenticated, selectUserPermissions } from '../redux/slices/userAuthSlice';
import NavBarComponent from '../components/navbar.js';
import FootComponent from '../components/foot.js';
import AIModelsDashboard from './dashboards/ai.models.js';
import AITasksDashboard from './dashboards/ai.tasks.js';
import RendersDashboard from './dashboards/renders.js';
import ServersDashboard from './dashboards/servers.js';
import UserSettingsDashboard from './dashboards/user.js';
import ThreeDModelsDashboard from './dashboards/3d-models.js';
const DashboardPage = () => {
const dispatch = useDispatch();
const isAuthenticated = useSelector(selectIsAuthenticated);
const permissions = useSelector(selectUserPermissions);
const icons_size = "fa-2x";
const [activeComponent, setActiveComponent] = useState('3d-models');
useEffect(() => {
if (!isAuthenticated) {
dispatch(checkAuth())
.unwrap()
.catch(() => {
navigate('/auth/login');
});
}
}, [dispatch, isAuthenticated]);
const handleNavigation = (path) => {
setActiveComponent(path);
};
const isActive = (path) => {
return activeComponent === path;
};
const handleLogout = async () => {
try {
await dispatch(logoutUser()).unwrap();
navigate('/auth/login');
} catch (error) {
console.error('Błąd podczas wylogowywania:', error);
}
};
const renderContent = () => {
switch (activeComponent) {
case 'ai-models':
return <AIModelsDashboard />;
case 'ai-tasks':
return <AITasksDashboard />;
case 'renders':
return <RendersDashboard />;
case 'servers':
return <ServersDashboard />;
case 'settings':
return <UserSettingsDashboard />;
case '3d-models':
default:
return <ThreeDModelsDashboard />;
}
};
return (
<>
<NavBarComponent />
<div className="dashboard-container" style={{"display": "flex"}}>
<main className="dashboard-content">
{renderContent()}
</main>
<main className="large-menu-content">
<p>Servers</p>
<ol>
<li
className={isActive('servers') ? 'active' : ''}
onClick={() => handleNavigation('servers')}
>
<i className={"fas " + icons_size + " fa-server"}></i>
<p>GPU Instances</p>
</li>
</ol>
<p>3D Stuff</p>
<ol>
<li
className={isActive('3d-models') ? 'active' : ''}
onClick={() => handleNavigation('3d-models')}
>
<i className={"fas " + icons_size + " fa-cube"}></i>
<p>3D Models</p>
</li>
<li
className={isActive('renders') ? 'active' : ''}
onClick={() => handleNavigation('renders')}
>
<i className={"fas " + icons_size + " fa-paint-brush"}></i>
<p>3D Rendering</p>
</li>
</ol>
<p>AI Stuff</p>
<ol>
<li
className={isActive('ai-models') ? 'active' : ''}
onClick={() => handleNavigation('ai-models')}
>
<i className={"fas " + icons_size + " fa-robot"}></i>
<p>AI Models</p>
</li>
<li
className={isActive('ai-tasks') ? 'active' : ''}
onClick={() => handleNavigation('ai-tasks')}
>
<i className={"fas " + icons_size + " fa-microchip"}></i>
<p>AI Training</p>
</li>
</ol>
<p>User</p>
<ol>
<li
className={isActive('settings') ? 'active' : ''}
onClick={() => handleNavigation('settings')}
>
<i className={"fas " + icons_size + " fa-user-cog"}></i>
<p>Settings</p>
</li>
<li onClick={handleLogout}>
<i className={"fas " + icons_size + " fa-sign-out-alt"}></i>
<p>Log Out</p>
</li>
</ol>
</main>
</div>
<FootComponent />
</>
);
};
export default DashboardPage;

View File

@ -1,408 +0,0 @@
import React, { useState, useMemo } from 'react';
import { ListGenerator } from '../../components/forms/listGenerator';
import ModelUploadForm from '../../components/forms/3d_model_crud/threeDModelUpload';
const ThreeDModelsDashboard = () => {
const [selectedModel, setSelectedModel] = useState(null);
const [searchQuery, setSearchQuery] = useState('');
const [models, setModels] = useState([
{
id: 1,
name: 'Dragon Model',
type: 'Blender',
status: 'Active',
lastModified: '2024-03-20',
version: '2.1'
},
{
id: 2,
name: 'Medieval Castle',
type: 'Maya',
status: 'Inactive',
lastModified: '2024-03-19',
version: '1.5'
},
{
id: 3,
name: 'Sci-fi Weapon',
type: '3ds Max',
status: 'Active',
lastModified: '2024-03-20',
version: '1.0'
},
{
id: 4,
name: 'Forest Scene',
type: 'Blender',
status: 'Active',
lastModified: '2024-03-18',
version: '3.2'
},
{
id: 5,
name: 'Robot Character',
type: 'Maya',
status: 'Inactive',
lastModified: '2024-03-17',
version: '2.0'
},
{
id: 6,
name: 'Space Ship',
type: '3ds Max',
status: 'Active',
lastModified: '2024-03-20',
version: '1.8'
},
{
id: 7,
name: 'Ancient Temple',
type: 'Blender',
status: 'Active',
lastModified: '2024-03-19',
version: '2.4'
},
{
id: 8,
name: 'Fantasy Sword',
type: 'Maya',
status: 'Inactive',
lastModified: '2024-03-16',
version: '1.2'
},
{
id: 9,
name: 'City Block',
type: '3ds Max',
status: 'Active',
lastModified: '2024-03-20',
version: '2.7'
},
{
id: 10,
name: 'Warrior Character',
type: 'Blender',
status: 'Active',
lastModified: '2024-03-18',
version: '1.9'
},
{
id: 11,
name: 'Futuristic Car',
type: 'Maya',
status: 'Inactive',
lastModified: '2024-03-15',
version: '1.3'
},
{
id: 12,
name: 'Mountain Range',
type: '3ds Max',
status: 'Active',
lastModified: '2024-03-20',
version: '2.2'
},
{
id: 13,
name: 'Alien Creature',
type: 'Blender',
status: 'Active',
lastModified: '2024-03-19',
version: '1.6'
},
{
id: 14,
name: 'Magic Staff',
type: 'Maya',
status: 'Active',
lastModified: '2024-03-20',
version: '1.4'
},
{
id: 15,
name: 'Underground Cave',
type: '3ds Max',
status: 'Inactive',
lastModified: '2024-03-17',
version: '2.3'
}
]);
const [isFormVisible, setIsFormVisible] = useState(false);
const [formMode, setFormMode] = useState('create');
const [message, setMessage] = useState({ type: '', text: '' });
const mockModels = [
{
id: 1,
name: "Dragon Model",
type: "Character",
status: "Completed",
progress: 100
},
{
id: 2,
name: "Medieval Castle",
type: "Environment",
status: "In Progress",
progress: 65
},
{
id: 3,
name: "Sci-fi Weapon",
type: "Prop",
status: "Queued",
progress: 0
},
{
id: 4,
name: "Forest Scene",
type: "Environment",
status: "Completed",
progress: 100
},
{
id: 5,
name: "Robot Character",
type: "Character",
status: "In Progress",
progress: 45
},
{
id: 6,
name: "Space Ship",
type: "Vehicle",
status: "Completed",
progress: 100
},
{
id: 7,
name: "Ancient Temple",
type: "Environment",
status: "In Progress",
progress: 78
},
{
id: 8,
name: "Fantasy Sword",
type: "Prop",
status: "Queued",
progress: 0
},
{
id: 9,
name: "City Block",
type: "Environment",
status: "Completed",
progress: 100
},
{
id: 10,
name: "Warrior Character",
type: "Character",
status: "In Progress",
progress: 89
},
{
id: 11,
name: "Futuristic Car",
type: "Vehicle",
status: "Queued",
progress: 0
},
{
id: 12,
name: "Mountain Range",
type: "Environment",
status: "Completed",
progress: 100
},
{
id: 13,
name: "Alien Creature",
type: "Character",
status: "In Progress",
progress: 34
},
{
id: 14,
name: "Magic Staff",
type: "Prop",
status: "Completed",
progress: 100
},
{
id: 15,
name: "Underground Cave",
type: "Environment",
status: "In Progress",
progress: 56
}
];
const handleModelSelect = (model) => {
setSelectedModel(model);
};
const handleModelAction = (action, model) => {
switch (action) {
case 'delete':
handleDeleteModel(model.id);
break;
case 'edit':
handleEditModel(model);
break;
default:
console.log('Unknown action:', action);
}
};
const handleCreateModel = () => {
setFormMode('create');
setIsFormVisible(true);
setSelectedModel(null);
};
const handleEditModel = (model) => {
setFormMode('edit');
setIsFormVisible(true);
setSelectedModel(model);
};
const handleDeleteModel = (modelId) => {
setModels(models.filter(model => model.id !== modelId));
if (selectedModel?.id === modelId) {
setSelectedModel(null);
}
setMessage({ type: 'success', text: '3D Model has been deleted' });
};
const handleFormCancel = () => {
setIsFormVisible(false);
setSelectedModel(null);
};
const getModelActions = (model) => {
return [
{
label: 'Edit',
action: 'edit',
className: 'update-button'
},
{
label: 'Delete',
action: 'delete',
className: 'delete-button'
}
];
};
const filteredModels = useMemo(() => {
return models.filter(model =>
model.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
model.type.toLowerCase().includes(searchQuery.toLowerCase()) ||
model.status.toLowerCase().includes(searchQuery.toLowerCase())
);
}, [models, searchQuery]);
return (
<div className="list-container">
<div className="dashboard-header">
<h2>3D Models</h2>
<div className="dashboard-controls">
<div className="search-container">
<input
type="text"
placeholder="Szukaj modeli..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="search-input"
/>
{searchQuery && (
<button
className="clear-search"
onClick={() => setSearchQuery('')}
>
×
</button>
)}
</div>
<button
className="create-button"
onClick={handleCreateModel}
>
<i className="fas fa-upload"></i>
Upload 3D Model
</button>
</div>
</div>
{message.text && (
<div className={`message ${message.type}`}>
{message.text}
</div>
)}
{isFormVisible && (
<div className="form-overlay">
<div className="form-container">
<ModelUploadForm/>
</div>
</div>
)}
<ListGenerator
data={filteredModels}
selectedItem={selectedModel}
onItemSelect={handleModelSelect}
onItemAction={handleModelAction}
getItemActions={getModelActions}
renderItem={(model) => (
<div className="list-row">
<div className="item-info">
<div className="item-name">{model.name}</div>
<div className="item-type">{model.type}</div>
<div className={`item-status ${model.status.toLowerCase()}`}>
{model.status}
</div>
</div>
<div className="item-details">
<div>Version: {model.version}</div>
<div>Last Modified: {model.lastModified}</div>
</div>
</div>
)}
renderDetails={(model) => (
<div className="details-panel">
<h3>3D Model Details</h3>
<div className="detail-row">
<span className="detail-label">ID:</span>
<span className="detail-value">{model.id}</span>
</div>
<div className="detail-row">
<span className="detail-label">Name:</span>
<span className="detail-value">{model.name}</span>
</div>
<div className="detail-row">
<span className="detail-label">Type:</span>
<span className="detail-value">{model.type}</span>
</div>
<div className="detail-row">
<span className="detail-label">Version:</span>
<span className="detail-value">{model.version}</span>
</div>
<div className="detail-row">
<span className="detail-label">Status:</span>
<span className="detail-value">{model.status}</span>
</div>
<div className="detail-row">
<span className="detail-label">Last Modified:</span>
<span className="detail-value">{model.lastModified}</span>
</div>
</div>
)}
/>
</div>
);
};
export default ThreeDModelsDashboard;

View File

@ -1,385 +0,0 @@
import React, { useState, useRef, useMemo } from 'react';
import { ListGenerator } from '../../components/forms/listGenerator';
import FormGenerator from '../../components/forms/formGenerator';
import AIModelUploadForm from '../../components/forms/ai_model_crud/AIModelUpload';
const AIModelsDashboard = () => {
const [selectedModel, setSelectedModel] = useState(null);
const [searchQuery, setSearchQuery] = useState('');
const [models, setModels] = useState([
{
id: 1,
name: 'stable-diffusion',
type: 'text-to-image',
status: 'Active',
lastModified: '2024-03-20',
version: '2.1'
},
{
id: 2,
name: 'gpt-4',
type: 'text-generation',
status: 'Inactive',
lastModified: '2024-03-19',
version: '1.0'
},
{
id: 3,
name: 'yolo-v8',
type: 'object-detection',
status: 'Active',
lastModified: '2024-03-20',
version: '1.2'
},
{
id: 4,
name: 'wav2vec',
type: 'speech-recognition',
status: 'Active',
lastModified: '2024-03-18',
version: '3.0'
},
{
id: 5,
name: 'bert-base',
type: 'text-classification',
status: 'Inactive',
lastModified: '2024-03-17',
version: '2.0'
},
{
id: 6,
name: 'resnet-50',
type: 'image-classification',
status: 'Active',
lastModified: '2024-03-20',
version: '1.8'
},
{
id: 7,
name: 'detr',
type: 'object-detection',
status: 'Active',
lastModified: '2024-03-19',
version: '2.4'
},
{
id: 8,
name: 'whisper',
type: 'speech-recognition',
status: 'Inactive',
lastModified: '2024-03-16',
version: '1.2'
},
{
id: 9,
name: 'dalle-3',
type: 'text-to-image',
status: 'Active',
lastModified: '2024-03-20',
version: '2.7'
},
{
id: 10,
name: 'llama-2',
type: 'text-generation',
status: 'Active',
lastModified: '2024-03-18',
version: '1.9'
},
{
id: 11,
name: 'mask-rcnn',
type: 'image-segmentation',
status: 'Inactive',
lastModified: '2024-03-15',
version: '1.3'
},
{
id: 12,
name: 'roberta',
type: 'text-classification',
status: 'Active',
lastModified: '2024-03-20',
version: '2.2'
},
{
id: 13,
name: 'dino',
type: 'image-classification',
status: 'Active',
lastModified: '2024-03-19',
version: '1.6'
},
{
id: 14,
name: 'sam',
type: 'image-segmentation',
status: 'Active',
lastModified: '2024-03-20',
version: '1.4'
},
{
id: 15,
name: 'clip',
type: 'image-text',
status: 'Inactive',
lastModified: '2024-03-17',
version: '2.3'
}
]);
const [isFormVisible, setIsFormVisible] = useState(false);
const [formMode, setFormMode] = useState('create');
const [message, setMessage] = useState({ type: '', text: '' });
const nameInput = React.createRef();
const typeInput = React.createRef();
const versionInput = React.createRef();
const statusInput = React.createRef();
const formRefs = [
nameInput,
typeInput,
versionInput,
statusInput
];
const inputList = [
{
type: 'info',
action: formMode === 'create' ? 'Create' : 'Update',
endpoint: 'ai/models',
button_value: formMode === 'create' ? '+ AI MODEL' : 'UPDATE',
allowButtonAction: false
},
{
type: 'text',
name: 'NAME',
ref: nameInput,
value: selectedModel?.name || '',
onChange: null,
validationInfo: null
},
{
type: 'select',
name: 'TYPE',
ref: typeInput,
options: [
{ value: 'text-to-image', label: 'Text to Image' },
{ value: 'image-to-text', label: 'Image to Text' }
],
value: selectedModel?.type || 'text-to-image',
onChange: null,
validationInfo: null
},
{
type: 'text',
name: 'VERSION',
ref: versionInput,
value: selectedModel?.version || '1.0',
onChange: null,
validationInfo: null
},
{
type: 'select',
name: 'STATUS',
ref: statusInput,
options: [
{ value: 'Active', label: 'Active' },
{ value: 'Inactive', label: 'Inactive' }
],
value: selectedModel?.status || 'Active',
onChange: null,
validationInfo: null
}
];
const handleModelSelect = (model) => {
setSelectedModel(model);
};
const handleModelAction = (action, model) => {
switch (action) {
case 'delete':
handleDeleteModel(model.id);
break;
case 'edit':
handleEditModel(model);
break;
default:
console.log('Unknown action:', action);
}
};
const handleCreateModel = () => {
setFormMode('create');
setIsFormVisible(true);
setSelectedModel(null);
};
const handleEditModel = (model) => {
setFormMode('edit');
setIsFormVisible(true);
setSelectedModel(model);
};
const handleDeleteModel = (modelId) => {
setModels(models.filter(model => model.id !== modelId));
if (selectedModel?.id === modelId) {
setSelectedModel(null);
}
setMessage({ type: 'success', text: 'AI Model has been deleted' });
};
const handleFormSubmit = (formData) => {
if (formMode === 'create') {
const newModel = {
id: models.length + 1,
...formData,
lastModified: new Date().toISOString().split('T')[0],
status: 'Active'
};
setModels([...models, newModel]);
setMessage({ type: 'success', text: 'AI Model has been created' });
} else {
setModels(models.map(model =>
model.id === selectedModel.id
? { ...model, ...formData, lastModified: new Date().toISOString().split('T')[0] }
: model
));
setMessage({ type: 'success', text: 'AI Model has been updated' });
}
setIsFormVisible(false);
};
const handleFormCancel = () => {
setIsFormVisible(false);
setSelectedModel(null);
};
const getModelActions = (model) => {
return [
{
label: 'Edit',
action: 'edit',
className: 'update-button'
},
{
label: 'Delete',
action: 'delete',
className: 'delete-button'
}
];
};
const filteredModels = useMemo(() => {
return models.filter(model =>
model.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
model.type.toLowerCase().includes(searchQuery.toLowerCase()) ||
model.status.toLowerCase().includes(searchQuery.toLowerCase())
);
}, [models, searchQuery]);
return (
<div className="list-container">
<div className="dashboard-header">
<h2>AI Models</h2>
<div className="dashboard-controls">
<div className="search-container">
<input
type="text"
placeholder="Szukaj modeli..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="search-input"
/>
{searchQuery && (
<button
className="clear-search"
onClick={() => setSearchQuery('')}
>
×
</button>
)}
</div>
<button
className="create-button"
onClick={() => setIsFormVisible(true)}
>
<i className="fas fa-upload"></i>
Upload AI Model
</button>
</div>
</div>
{message.text && (
<div className={`message ${message.type}`}>
{message.text}
</div>
)}
{isFormVisible && (
<div className="form-overlay">
<div className="form-container">
<AIModelUploadForm />
</div>
</div>
)}
<ListGenerator
data={filteredModels}
selectedItem={selectedModel}
onItemSelect={handleModelSelect}
onItemAction={handleModelAction}
getItemActions={getModelActions}
renderItem={(model) => (
<div className="list-row">
<div className="item-info">
<div className="item-name">{model.name}</div>
<div className="item-type">{model.type}</div>
<div className={`item-status ${model.status.toLowerCase()}`}>
{model.status}
</div>
</div>
<div className="item-details">
<div>Version: {model.version}</div>
<div>Last Modified: {model.lastModified}</div>
</div>
</div>
)}
renderDetails={(model) => (
<div className="details-panel">
<h3>AI Model Details</h3>
<div className="detail-row">
<span className="detail-label">ID:</span>
<span className="detail-value">{model.id}</span>
</div>
<div className="detail-row">
<span className="detail-label">Name:</span>
<span className="detail-value">{model.name}</span>
</div>
<div className="detail-row">
<span className="detail-label">Type:</span>
<span className="detail-value">{model.type}</span>
</div>
<div className="detail-row">
<span className="detail-label">Version:</span>
<span className="detail-value">{model.version}</span>
</div>
<div className="detail-row">
<span className="detail-label">Status:</span>
<span className="detail-value">{model.status}</span>
</div>
<div className="detail-row">
<span className="detail-label">Last Modified:</span>
<span className="detail-value">{model.lastModified}</span>
</div>
</div>
)}
/>
</div>
);
};
export default AIModelsDashboard;

View File

@ -1,482 +0,0 @@
import React, { useState, useRef, useMemo } from 'react';
import { ListGenerator } from '../../components/forms/listGenerator';
import FormGenerator from '../../components/forms/formGenerator';
const AITasksDashboard = () => {
const [selectedTask, setSelectedTask] = useState(null);
const [searchQuery, setSearchQuery] = useState('');
const [tasks, setTasks] = useState([
{
id: 1,
name: "Model Training - CNN",
type: "Training",
status: "Completed",
progress: 100,
model: "Object Detection v2",
startTime: "2024-03-20 09:00:00",
endTime: "2024-03-20 14:30:00"
},
{
id: 2,
name: "BERT Fine-tuning",
type: "Fine-tuning",
status: "In Progress",
progress: 75,
model: "Text Generator",
startTime: "2024-03-20 10:15:00",
endTime: null
},
{
id: 3,
name: "Model Evaluation",
type: "Evaluation",
status: "Queued",
progress: 0,
model: "Style Transfer v1",
startTime: null,
endTime: null
},
{
id: 4,
name: "Performance Testing",
type: "Testing",
status: "Completed",
progress: 100,
model: "Face Recognition",
startTime: "2024-03-19 15:00:00",
endTime: "2024-03-19 17:30:00"
},
{
id: 5,
name: "Model Training - RNN",
type: "Training",
status: "In Progress",
progress: 60,
model: "Language Translator",
startTime: "2024-03-20 08:45:00",
endTime: null
},
{
id: 6,
name: "GAN Training",
type: "Training",
status: "Completed",
progress: 100,
model: "Image Generation",
startTime: "2024-03-19 11:00:00",
endTime: "2024-03-19 18:30:00"
},
{
id: 7,
name: "Model Optimization",
type: "Fine-tuning",
status: "In Progress",
progress: 82,
model: "Voice Synthesis",
startTime: "2024-03-20 09:30:00",
endTime: null
},
{
id: 8,
name: "Accuracy Testing",
type: "Testing",
status: "Queued",
progress: 0,
model: "Pose Estimation",
startTime: null,
endTime: null
},
{
id: 9,
name: "Transfer Learning",
type: "Training",
status: "Completed",
progress: 100,
model: "Scene Understanding",
startTime: "2024-03-19 13:15:00",
endTime: "2024-03-19 16:45:00"
},
{
id: 10,
name: "Model Validation",
type: "Evaluation",
status: "In Progress",
progress: 45,
model: "Text Summarizer",
startTime: "2024-03-20 11:00:00",
endTime: null
},
{
id: 11,
name: "Hyperparameter Tuning",
type: "Fine-tuning",
status: "Queued",
progress: 0,
model: "Speech Recognition",
startTime: null,
endTime: null
},
{
id: 12,
name: "Model Training - YOLO",
type: "Training",
status: "Completed",
progress: 100,
model: "Object Tracking",
startTime: "2024-03-19 09:00:00",
endTime: "2024-03-19 15:30:00"
},
{
id: 13,
name: "Performance Optimization",
type: "Fine-tuning",
status: "In Progress",
progress: 68,
model: "Image Segmentation",
startTime: "2024-03-20 10:00:00",
endTime: null
},
{
id: 14,
name: "Model Deployment Test",
type: "Testing",
status: "Completed",
progress: 100,
model: "Sentiment Analysis",
startTime: "2024-03-19 14:00:00",
endTime: "2024-03-19 16:00:00"
},
{
id: 15,
name: "Model Training - GPT",
type: "Training",
status: "In Progress",
progress: 92,
model: "Chatbot Model",
startTime: "2024-03-20 07:30:00",
endTime: null
}
]);
const [isFormVisible, setIsFormVisible] = useState(false);
const [formMode, setFormMode] = useState('create');
const [message, setMessage] = useState({ type: '', text: '' });
const nameInput = React.createRef();
const typeInput = React.createRef();
const statusInput = React.createRef();
const progressInput = React.createRef();
const formRefs = [
nameInput,
typeInput,
statusInput,
progressInput
];
const inputList = [
{
type: 'info',
action: formMode === 'create' ? 'Create' : 'Update',
endpoint: 'ai/tasks',
button_value: formMode === 'create' ? '+ AI TASK' : 'UPDATE',
allowButtonAction: false
},
{
type: 'text',
name: 'NAME',
ref: nameInput,
value: selectedTask?.name || '',
onChange: null,
validationInfo: null
},
{
type: 'select',
name: 'TYPE',
ref: typeInput,
options: [
{ value: 'text-to-image', label: 'Text to Image' },
{ value: 'image-to-text', label: 'Image to Text' }
],
value: selectedTask?.type || 'text-to-image',
onChange: null,
validationInfo: null
},
{
type: 'select',
name: 'STATUS',
ref: statusInput,
options: [
{ value: 'In Progress', label: 'In Progress' },
{ value: 'Completed', label: 'Completed' },
{ value: 'Failed', label: 'Failed' },
{ value: 'Cancelled', label: 'Cancelled' }
],
value: selectedTask?.status || 'In Progress',
onChange: null,
validationInfo: null
},
{
type: 'number',
name: 'PROGRESS',
ref: progressInput,
value: selectedTask?.progress || 0,
min: 0,
max: 100,
onChange: null,
validationInfo: null
}
];
const handleTaskSelect = (task) => {
setSelectedTask(task);
};
const handleTaskAction = (action, task) => {
switch (action) {
case 'delete':
handleDeleteTask(task.id);
break;
case 'edit':
handleEditTask(task);
break;
case 'cancel':
handleCancelTask(task.id);
break;
case 'restart':
handleRestartTask(task.id);
break;
default:
console.log('Unknown action:', action);
}
};
const handleCreateTask = () => {
setFormMode('create');
setIsFormVisible(true);
setSelectedTask(null);
};
const handleEditTask = (task) => {
setFormMode('edit');
setIsFormVisible(true);
setSelectedTask(task);
};
const handleDeleteTask = (taskId) => {
setTasks(tasks.filter(task => task.id !== taskId));
if (selectedTask?.id === taskId) {
setSelectedTask(null);
}
setMessage({ type: 'success', text: 'Task has been deleted' });
};
const handleCancelTask = (taskId) => {
setTasks(tasks.map(task =>
task.id === taskId
? { ...task, status: 'Cancelled', progress: 0 }
: task
));
setMessage({ type: 'success', text: 'Task has been cancelled' });
};
const handleRestartTask = (taskId) => {
setTasks(tasks.map(task =>
task.id === taskId
? { ...task, status: 'In Progress', progress: 0 }
: task
));
setMessage({ type: 'success', text: 'Task has been restarted' });
};
const handleFormSubmit = (formData) => {
if (formMode === 'create') {
const newTask = {
id: tasks.length + 1,
...formData,
lastModified: new Date().toISOString().split('T')[0],
status: 'In Progress',
progress: 0
};
setTasks([...tasks, newTask]);
setMessage({ type: 'success', text: 'Task has been created' });
} else {
setTasks(tasks.map(task =>
task.id === selectedTask.id
? { ...task, ...formData, lastModified: new Date().toISOString().split('T')[0] }
: task
));
setMessage({ type: 'success', text: 'Task has been updated' });
}
setIsFormVisible(false);
};
const handleFormCancel = () => {
setIsFormVisible(false);
setSelectedTask(null);
};
const handleFormAction = (refs) => {
const formData = {};
refs.forEach((ref, index) => {
formData[inputList[index].name] = ref.current.value;
});
handleFormSubmit(formData);
};
const getTaskActions = (task) => {
const actions = [];
if (task.status === 'In Progress') {
actions.push({
label: 'Cancel',
action: 'cancel',
className: 'cancel-button'
});
} else if (task.status === 'Completed' || task.status === 'Cancelled') {
actions.push({
label: 'Restart',
action: 'restart',
className: 'restart-button'
});
}
actions.push(
{
label: 'Edit',
action: 'edit',
className: 'update-button'
},
{
label: 'Delete',
action: 'delete',
className: 'delete-button'
}
);
return actions;
};
const filteredTasks = useMemo(() => {
return tasks.filter(task =>
task.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
task.type.toLowerCase().includes(searchQuery.toLowerCase()) ||
task.status.toLowerCase().includes(searchQuery.toLowerCase()) ||
task.model.toLowerCase().includes(searchQuery.toLowerCase())
);
}, [tasks, searchQuery]);
return (
<div className="list-container">
<div className="dashboard-header">
<h2>AI Training</h2>
<div className="dashboard-controls">
<div className="search-container">
<input
type="text"
placeholder="Szukaj zadań..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="search-input"
/>
{searchQuery && (
<button
className="clear-search"
onClick={() => setSearchQuery('')}
>
×
</button>
)}
</div>
<button
className="create-button"
onClick={handleCreateTask}
>
<i className="fas fa-plus"></i>
Create Task
</button>
</div>
</div>
{message.text && (
<div className={`message ${message.type}`}>
{message.text}
</div>
)}
{isFormVisible && (
<div className="form-overlay">
<div className="form-container">
<FormGenerator
inputList={inputList}
formRefs={formRefs}
onSubmit={handleFormSubmit}
onCancel={handleFormCancel}
/>
</div>
</div>
)}
<ListGenerator
data={filteredTasks}
selectedItem={selectedTask}
onItemSelect={handleTaskSelect}
onItemAction={handleTaskAction}
getItemActions={getTaskActions}
renderItem={(task) => (
<div className="list-row">
<div className="item-info">
<div className="item-name">{task.name}</div>
<div className="item-type">{task.type}</div>
<div className={`item-status ${task.status.toLowerCase().replace(' ', '-')}`}>
{task.status}
</div>
<div className="item-progress">
<div className="progress-bar">
<div
className="progress-fill"
style={{ width: `${task.progress}%` }}
/>
</div>
<span>{task.progress}%</span>
</div>
</div>
<div className="item-details">
<div>Last Modified: {task.lastModified}</div>
</div>
</div>
)}
renderDetails={(task) => (
<div className="details-panel">
<h3>Task Details</h3>
<div className="detail-row">
<span className="detail-label">ID:</span>
<span className="detail-value">{task.id}</span>
</div>
<div className="detail-row">
<span className="detail-label">Name:</span>
<span className="detail-value">{task.name}</span>
</div>
<div className="detail-row">
<span className="detail-label">Type:</span>
<span className="detail-value">{task.type}</span>
</div>
<div className="detail-row">
<span className="detail-label">Status:</span>
<span className="detail-value">{task.status}</span>
</div>
<div className="detail-row">
<span className="detail-label">Progress:</span>
<span className="detail-value">{task.progress}%</span>
</div>
<div className="detail-row">
<span className="detail-label">Last Modified:</span>
<span className="detail-value">{task.lastModified}</span>
</div>
</div>
)}
/>
</div>
);
};
export default AITasksDashboard;

View File

@ -1,570 +0,0 @@
import React, { useState, useRef, useMemo } from 'react';
import { ListGenerator } from '../../components/forms/listGenerator';
import FormGenerator from '../../components/forms/formGenerator';
const RendersDashboard = () => {
const [selectedRender, setSelectedRender] = useState(null);
const [renders, setRenders] = useState([
{
id: 1,
name: "Character Animation",
type: "Animation",
status: "Completed",
progress: 100,
model: "Hero Character",
startTime: "2024-03-20 09:00:00",
endTime: "2024-03-20 11:30:00"
},
{
id: 2,
name: "Environment Lighting",
type: "Still",
status: "In Progress",
progress: 75,
model: "Forest Scene",
startTime: "2024-03-20 10:15:00",
endTime: null
},
{
id: 3,
name: "Product Showcase",
type: "360 View",
status: "Queued",
progress: 0,
model: "Sports Car",
startTime: null,
endTime: null
},
{
id: 4,
name: "Battle Scene",
type: "Animation",
status: "Completed",
progress: 100,
model: "Warriors",
startTime: "2024-03-19 15:00:00",
endTime: "2024-03-19 18:30:00"
},
{
id: 5,
name: "Architectural Visualization",
type: "Still",
status: "In Progress",
progress: 60,
model: "Modern House",
startTime: "2024-03-20 08:45:00",
endTime: null
},
{
id: 6,
name: "Character Portrait",
type: "Still",
status: "Completed",
progress: 100,
model: "Fantasy Character",
startTime: "2024-03-19 11:00:00",
endTime: "2024-03-19 12:30:00"
},
{
id: 7,
name: "Vehicle Animation",
type: "Animation",
status: "In Progress",
progress: 82,
model: "Racing Car",
startTime: "2024-03-20 09:30:00",
endTime: null
},
{
id: 8,
name: "Product Display",
type: "360 View",
status: "Queued",
progress: 0,
model: "Smartphone",
startTime: null,
endTime: null
},
{
id: 9,
name: "Nature Scene",
type: "Still",
status: "Completed",
progress: 100,
model: "Mountain Landscape",
startTime: "2024-03-19 13:15:00",
endTime: "2024-03-19 15:45:00"
},
{
id: 10,
name: "Character Walk Cycle",
type: "Animation",
status: "In Progress",
progress: 45,
model: "Robot Character",
startTime: "2024-03-20 11:00:00",
endTime: null
},
{
id: 11,
name: "Jewelry Showcase",
type: "360 View",
status: "Queued",
progress: 0,
model: "Diamond Ring",
startTime: null,
endTime: null
},
{
id: 12,
name: "City Flythrough",
type: "Animation",
status: "Completed",
progress: 100,
model: "Future City",
startTime: "2024-03-19 09:00:00",
endTime: "2024-03-19 14:30:00"
},
{
id: 13,
name: "Interior Design",
type: "Still",
status: "In Progress",
progress: 68,
model: "Living Room",
startTime: "2024-03-20 10:00:00",
endTime: null
},
{
id: 14,
name: "Product Animation",
type: "Animation",
status: "Completed",
progress: 100,
model: "Gaming Console",
startTime: "2024-03-19 14:00:00",
endTime: "2024-03-19 16:00:00"
},
{
id: 15,
name: "Character Showcase",
type: "360 View",
status: "In Progress",
progress: 92,
model: "Superhero",
startTime: "2024-03-20 07:30:00",
endTime: null
}
]);
const [isFormVisible, setIsFormVisible] = useState(false);
const [formMode, setFormMode] = useState('create');
const [message, setMessage] = useState({ type: '', text: '' });
const [searchQuery, setSearchQuery] = useState('');
const nameInput = React.createRef();
const typeInput = React.createRef();
const resolutionInput = React.createRef();
const threeDModelInput = React.createRef();
const formRefs = [
nameInput,
typeInput,
resolutionInput,
threeDModelInput
];
const inputList = [
{
type: 'info',
action: formMode === 'create' ? 'Create' : 'Update',
endpoint: 'renders',
button_value: formMode === 'create' ? '+ RENDER' : 'UPDATE',
allowButtonAction: false
},
{
type: 'text',
name: 'Name',
ref: nameInput,
value: selectedRender?.name || '',
onChange: null,
validationInfo: null
},
{
type: 'text',
name: 'Resolution',
ref: resolutionInput,
value: selectedRender?.resolution || '',
onChange: null,
validationInfo: null
},
{
type: 'choice-listing',
name: '3D Model',
ref: threeDModelInput,
values: selectedRender?.threeDModel|| '',
onChange: null,
validationInfo: null
},
];
const handleRenderSelect = (render) => {
setSelectedRender(render);
};
const handleRenderAction = (action, render) => {
switch (action) {
case 'delete':
handleDeleteRender(render.id);
break;
case 'edit':
handleEditRender(render);
break;
default:
console.log('Unknown action:', action);
}
};
const handleCreateRender = () => {
setFormMode('create');
setIsFormVisible(true);
setSelectedRender(null);
};
const handleEditRender = (render) => {
setFormMode('edit');
setIsFormVisible(true);
setSelectedRender(render);
};
const handleDeleteRender = (renderId) => {
setRenders(renders.filter(render => render.id !== renderId));
if (selectedRender?.id === renderId) {
setSelectedRender(null);
}
setMessage({ type: 'success', text: 'Render został usunięty' });
};
const handleFormSubmit = (formData) => {
if (formMode === 'create') {
const newRender = {
id: renders.length + 1,
...formData,
lastModified: new Date().toISOString().split('T')[0],
status: 'In Progress',
progress: 0
};
setRenders([...renders, newRender]);
setMessage({ type: 'success', text: 'Render został utworzony' });
} else {
setRenders(renders.map(render =>
render.id === selectedRender.id
? { ...render, ...formData, lastModified: new Date().toISOString().split('T')[0] }
: render
));
setMessage({ type: 'success', text: 'Render został zaktualizowany' });
}
setIsFormVisible(false);
};
const handleFormCancel = () => {
setIsFormVisible(false);
setSelectedRender(null);
};
const getRenderActions = (render) => {
return [
{
label: 'Edit',
action: 'edit',
className: 'update-button'
},
{
label: 'Delete',
action: 'delete',
className: 'delete-button'
}
];
};
const mockRenders = [
{
id: 1,
name: "Dragon Scene",
type: "Animation",
status: "Completed",
progress: 100,
model: "Dragon Model",
startTime: "2024-03-01 10:00:00",
endTime: "2024-03-01 12:30:00"
},
{
id: 2,
name: "Castle Exterior",
type: "Still",
status: "In Progress",
progress: 65,
model: "Medieval Castle",
startTime: "2024-03-02 09:00:00",
endTime: null
},
{
id: 3,
name: "Weapon Showcase",
type: "360 View",
status: "Queued",
progress: 0,
model: "Sci-fi Weapon",
startTime: null,
endTime: null
},
{
id: 4,
name: "Forest Flythrough",
type: "Animation",
status: "Completed",
progress: 100,
model: "Forest Scene",
startTime: "2024-03-01 14:00:00",
endTime: "2024-03-01 16:00:00"
},
{
id: 5,
name: "Robot Animation",
type: "Animation",
status: "In Progress",
progress: 45,
model: "Robot Character",
startTime: "2024-03-02 11:00:00",
endTime: null
},
{
id: 6,
name: "Spaceship Launch",
type: "Animation",
status: "Completed",
progress: 100,
model: "Space Ship",
startTime: "2024-03-01 13:00:00",
endTime: "2024-03-01 15:30:00"
},
{
id: 7,
name: "Temple Interior",
type: "Still",
status: "In Progress",
progress: 78,
model: "Ancient Temple",
startTime: "2024-03-02 10:00:00",
endTime: null
},
{
id: 8,
name: "Sword Display",
type: "360 View",
status: "Queued",
progress: 0,
model: "Fantasy Sword",
startTime: null,
endTime: null
},
{
id: 9,
name: "City Timelapse",
type: "Animation",
status: "Completed",
progress: 100,
model: "City Block",
startTime: "2024-03-01 09:00:00",
endTime: "2024-03-01 11:30:00"
},
{
id: 10,
name: "Warrior Battle",
type: "Animation",
status: "In Progress",
progress: 89,
model: "Warrior Character",
startTime: "2024-03-02 13:00:00",
endTime: null
},
{
id: 11,
name: "Car Showcase",
type: "360 View",
status: "Queued",
progress: 0,
model: "Futuristic Car",
startTime: null,
endTime: null
},
{
id: 12,
name: "Mountain Vista",
type: "Still",
status: "Completed",
progress: 100,
model: "Mountain Range",
startTime: "2024-03-01 15:00:00",
endTime: "2024-03-01 16:30:00"
},
{
id: 13,
name: "Alien Movement",
type: "Animation",
status: "In Progress",
progress: 34,
model: "Alien Creature",
startTime: "2024-03-02 14:00:00",
endTime: null
},
{
id: 14,
name: "Staff Effects",
type: "Animation",
status: "Completed",
progress: 100,
model: "Magic Staff",
startTime: "2024-03-01 16:00:00",
endTime: "2024-03-01 18:30:00"
},
{
id: 15,
name: "Cave Exploration",
type: "Animation",
status: "In Progress",
progress: 56,
model: "Underground Cave",
startTime: "2024-03-02 12:00:00",
endTime: null
}
];
const filteredRenders = useMemo(() => {
return renders.filter(render =>
render.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
render.type.toLowerCase().includes(searchQuery.toLowerCase()) ||
render.status.toLowerCase().includes(searchQuery.toLowerCase()) ||
render.model.toLowerCase().includes(searchQuery.toLowerCase())
);
}, [renders, searchQuery]);
return (
<div className="list-container">
<div className="dashboard-header">
<h2>3D Rendering</h2>
<div className="dashboard-controls">
<div className="search-container">
<input
type="text"
placeholder="Szukaj renderów..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="search-input"
/>
{searchQuery && (
<button
className="clear-search"
onClick={() => setSearchQuery('')}
>
×
</button>
)}
</div>
<button
className="create-button"
onClick={handleCreateRender}
>
<i className="fas fa-plus"></i>
Create Render
</button>
</div>
</div>
{message.text && (
<div className={`message ${message.type}`}>
{message.text}
</div>
)}
{isFormVisible && (
<div className="form-overlay">
<div className="form-container">
<FormGenerator
inputList={inputList}
refList={formRefs}
action={handleFormSubmit}
/>
</div>
</div>
)}
<ListGenerator
data={filteredRenders}
selectedItem={selectedRender}
onItemSelect={handleRenderSelect}
onItemAction={handleRenderAction}
getItemActions={getRenderActions}
renderItem={(render) => (
<div className="list-row">
<div className="item-info">
<div className="item-name">{render.name}</div>
<div className="item-type">{render.type}</div>
<div className={`item-status ${render.status.toLowerCase().replace(' ', '-')}`}>
{render.status}
</div>
<div className="item-progress">
<div className="progress-bar">
<div
className="progress-fill"
style={{ width: `${render.progress}%` }}
/>
</div>
<span>{render.progress}%</span>
</div>
</div>
<div className="item-details">
<div>Rozdzielczość: {render.resolution}</div>
<div>Ostatnia modyfikacja: {render.lastModified}</div>
</div>
</div>
)}
renderDetails={(render) => (
<div className="details-panel">
<h3>Szczegóły renderu</h3>
<div className="detail-row">
<span className="detail-label">ID:</span>
<span className="detail-value">{render.id}</span>
</div>
<div className="detail-row">
<span className="detail-label">Nazwa:</span>
<span className="detail-value">{render.name}</span>
</div>
<div className="detail-row">
<span className="detail-label">Typ:</span>
<span className="detail-value">{render.type}</span>
</div>
<div className="detail-row">
<span className="detail-label">Rozdzielczość:</span>
<span className="detail-value">{render.resolution}</span>
</div>
<div className="detail-row">
<span className="detail-label">Status:</span>
<span className="detail-value">{render.status}</span>
</div>
<div className="detail-row">
<span className="detail-label">Postęp:</span>
<span className="detail-value">{render.progress}%</span>
</div>
<div className="detail-row">
<span className="detail-label">Ostatnia modyfikacja:</span>
<span className="detail-value">{render.lastModified}</span>
</div>
</div>
)}
/>
</div>
);
};
export default RendersDashboard;

View File

@ -1,413 +0,0 @@
import React, { useState, useRef, useMemo } from 'react';
import { ListGenerator } from '../../components/forms/listGenerator';
import FormGenerator from '../../components/forms/formGenerator';
const ServersDashboard = () => {
const [selectedServer, setSelectedServer] = useState(null);
const [searchQuery, setSearchQuery] = useState('');
const [servers, setServers] = useState([
{
id: 1,
name: "Render Node 1",
type: "Render Node",
status: "Active",
progress: 100,
ip: "192.168.1.101",
lastActive: "2024-03-20 11:30:00"
},
{
id: 2,
name: "AI Training Node 1",
type: "AI Training Node",
status: "In Progress",
progress: 75,
ip: "192.168.1.102",
lastActive: "2024-03-20 11:29:00"
},
{
id: 3,
name: "Storage Server 1",
type: "Storage Server",
status: "Active",
progress: 100,
ip: "192.168.1.103",
lastActive: "2024-03-20 11:30:00"
},
{
id: 4,
name: "Render Node 2",
type: "Render Node",
status: "Inactive",
progress: 0,
ip: "192.168.1.104",
lastActive: "2024-03-20 10:15:00"
},
{
id: 5,
name: "AI Training Node 2",
type: "AI Training Node",
status: "Active",
progress: 100,
ip: "192.168.1.105",
lastActive: "2024-03-20 11:30:00"
},
{
id: 6,
name: "Storage Server 2",
type: "Storage Server",
status: "Active",
progress: 100,
ip: "192.168.1.106",
lastActive: "2024-03-20 11:30:00"
},
{
id: 7,
name: "Render Node 3",
type: "Render Node",
status: "In Progress",
progress: 82,
ip: "192.168.1.107",
lastActive: "2024-03-20 11:29:00"
},
{
id: 8,
name: "AI Training Node 3",
type: "AI Training Node",
status: "Queued",
progress: 0,
ip: "192.168.1.108",
lastActive: "2024-03-20 11:00:00"
},
{
id: 9,
name: "Storage Server 3",
type: "Storage Server",
status: "Active",
progress: 100,
ip: "192.168.1.109",
lastActive: "2024-03-20 11:30:00"
},
{
id: 10,
name: "Render Node 4",
type: "Render Node",
status: "In Progress",
progress: 45,
ip: "192.168.1.110",
lastActive: "2024-03-20 11:29:00"
},
{
id: 11,
name: "AI Training Node 4",
type: "AI Training Node",
status: "Active",
progress: 100,
ip: "192.168.1.111",
lastActive: "2024-03-20 11:30:00"
},
{
id: 12,
name: "Storage Server 4",
type: "Storage Server",
status: "Inactive",
progress: 0,
ip: "192.168.1.112",
lastActive: "2024-03-20 10:45:00"
},
{
id: 13,
name: "Render Node 5",
type: "Render Node",
status: "Active",
progress: 100,
ip: "192.168.1.113",
lastActive: "2024-03-20 11:30:00"
},
{
id: 14,
name: "AI Training Node 5",
type: "AI Training Node",
status: "In Progress",
progress: 68,
ip: "192.168.1.114",
lastActive: "2024-03-20 11:29:00"
},
{
id: 15,
name: "Storage Server 5",
type: "Storage Server",
status: "Active",
progress: 100,
ip: "192.168.1.115",
lastActive: "2024-03-20 11:30:00"
}
]);
const [isFormVisible, setIsFormVisible] = useState(false);
const [formMode, setFormMode] = useState('create');
const [message, setMessage] = useState({ type: '', text: '' });
const nameInput = React.createRef();
const typeInput = React.createRef();
const ipInput = React.createRef();
const statusInput = React.createRef();
const formRefs = [
nameInput,
typeInput,
ipInput,
statusInput
];
const inputList = [
{
type: 'info',
action: formMode === 'create' ? 'Create' : 'Update',
endpoint: 'servers',
button_value: formMode === 'create' ? '+ SERVER' : 'UPDATE'
},
{
type: 'text',
name: 'NAME',
ref: nameInput,
value: selectedServer?.name || '',
onChange: null,
validationInfo: null
},
{
type: 'select',
name: 'TYPE',
ref: typeInput,
options: [
{ value: 'Render', label: 'Render' },
{ value: 'AI', label: 'AI' },
{ value: 'Storage', label: 'Storage' }
],
value: selectedServer?.type || 'Render',
onChange: null,
validationInfo: null
},
{
type: 'text',
name: 'IP',
ref: ipInput,
value: selectedServer?.ip || '',
onChange: null,
validationInfo: null
},
{
type: 'select',
name: 'STATUS',
ref: statusInput,
options: [
{ value: 'Online', label: 'Online' },
{ value: 'Offline', label: 'Offline' },
{ value: 'Maintenance', label: 'Maintenance' }
],
value: selectedServer?.status || 'Offline',
onChange: null,
validationInfo: null
}
];
const handleServerSelect = (server) => {
setSelectedServer(server);
};
const handleServerAction = (action, server) => {
switch (action) {
case 'delete':
handleDeleteServer(server.id);
break;
case 'edit':
handleEditServer(server);
break;
default:
console.log('Unknown action:', action);
}
};
const handleCreateServer = () => {
setFormMode('create');
setIsFormVisible(true);
setSelectedServer(null);
};
const handleEditServer = (server) => {
setFormMode('edit');
setIsFormVisible(true);
setSelectedServer(server);
};
const handleDeleteServer = (serverId) => {
setServers(servers.filter(server => server.id !== serverId));
if (selectedServer?.id === serverId) {
setSelectedServer(null);
}
setMessage({ type: 'success', text: 'Serwer został usunięty' });
};
const handleFormSubmit = (formData) => {
if (formMode === 'create') {
const newServer = {
id: servers.length + 1,
...formData,
lastModified: new Date().toISOString().split('T')[0],
status: 'Offline'
};
setServers([...servers, newServer]);
setMessage({ type: 'success', text: 'Serwer został utworzony' });
} else {
setServers(servers.map(server =>
server.id === selectedServer.id
? { ...server, ...formData, lastModified: new Date().toISOString().split('T')[0] }
: server
));
setMessage({ type: 'success', text: 'Serwer został zaktualizowany' });
}
setIsFormVisible(false);
};
const handleFormCancel = () => {
setIsFormVisible(false);
setSelectedServer(null);
};
const getServerActions = (server) => {
return [
{
label: 'Edit',
action: 'edit',
className: 'update-button'
},
{
label: 'Delete',
action: 'delete',
className: 'delete-button'
}
];
};
const handleFormAction = (refs) => {
const formData = {};
refs.forEach((ref, index) => {
formData[inputList[index].name] = ref.current.value;
});
handleFormSubmit(formData);
};
const filteredServers = useMemo(() => {
return servers.filter(server =>
server.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
server.type.toLowerCase().includes(searchQuery.toLowerCase()) ||
server.status.toLowerCase().includes(searchQuery.toLowerCase()) ||
server.ip.toLowerCase().includes(searchQuery.toLowerCase())
);
}, [servers, searchQuery]);
return (
<div className="list-container">
<div className="dashboard-header">
<h2>GPU Instances</h2>
<div className="dashboard-controls">
<div className="search-container">
<input
type="text"
placeholder="Szukaj serwerów..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="search-input"
/>
{searchQuery && (
<button
className="clear-search"
onClick={() => setSearchQuery('')}
>
×
</button>
)}
</div>
<button
className="create-button"
onClick={handleCreateServer}
>
<i className="fas fa-plus"></i>
Add Server
</button>
</div>
</div>
{message.text && (
<div className={`message ${message.type}`}>
{message.text}
</div>
)}
{isFormVisible && (
<div className="form-overlay">
<div className="form-container">
<FormGenerator
inputList={inputList}
refList={formRefs}
action={handleFormAction}
/>
</div>
</div>
)}
<ListGenerator
data={filteredServers}
selectedItem={selectedServer}
onItemSelect={handleServerSelect}
onItemAction={handleServerAction}
getItemActions={getServerActions}
renderItem={(server) => (
<div className="list-row">
<div className="item-info">
<div className="item-name">{server.name}</div>
<div className="item-type">{server.type}</div>
<div className={`item-status ${server.status.toLowerCase()}`}>
{server.status}
</div>
</div>
<div className="item-details">
<div>IP: {server.ip}</div>
<div>Ostatnia modyfikacja: {server.lastModified}</div>
</div>
</div>
)}
renderDetails={(server) => (
<div className="details-panel">
<h3>Szczegóły serwera</h3>
<div className="detail-row">
<span className="detail-label">ID:</span>
<span className="detail-value">{server.id}</span>
</div>
<div className="detail-row">
<span className="detail-label">Nazwa:</span>
<span className="detail-value">{server.name}</span>
</div>
<div className="detail-row">
<span className="detail-label">Typ:</span>
<span className="detail-value">{server.type}</span>
</div>
<div className="detail-row">
<span className="detail-label">IP:</span>
<span className="detail-value">{server.ip}</span>
</div>
<div className="detail-row">
<span className="detail-label">Status:</span>
<span className="detail-value">{server.status}</span>
</div>
<div className="detail-row">
<span className="detail-label">Ostatnia modyfikacja:</span>
<span className="detail-value">{server.lastModified}</span>
</div>
</div>
)}
/>
</div>
);
};
export default ServersDashboard;

View File

@ -1,42 +0,0 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { selectCurrentUser } from '../../redux/slices/userAuthSlice';
import UserUpdateProfileForm from '../../components/forms/user_settings/userUpdateProfileForm';
import UserChangePasswordForm from '../../components/forms/user_settings/userChangePasswordForm';
import UserDeleteAccountForm from '../../components/forms/user_settings/userDeleteAccountForm';
const UserSettingsDashboard = () => {
const user = useSelector(selectCurrentUser);
return (
<div className="dashboard-container">
<div className="dashboard-header">
<h1>Panel Użytkownika</h1>
<div className="user-info">
<span>Zalogowany jako: {user?.login}</span>
</div>
</div>
<div className="dashboard-content">
<div className="user-settings">
<div className="settings-section">
<h2>Aktualizacja profilu</h2>
<UserUpdateProfileForm />
</div>
<div className="settings-section">
<h2>Zmiana hasła</h2>
<UserChangePasswordForm />
</div>
<div className="settings-section">
<h2>Usuwanie konta</h2>
<UserDeleteAccountForm />
</div>
</div>
</div>
</div>
);
};
export default UserSettingsDashboard;

View File

@ -1,11 +1,150 @@
import React from 'react';
import * as React from "react"
// styles
const pageStyles = {
color: "#232129",
padding: "96px",
fontFamily: "-apple-system, Roboto, sans-serif, serif",
}
const headingStyles = {
marginTop: 0,
marginBottom: 64,
maxWidth: 320,
}
const headingAccentStyles = {
color: "#663399",
}
const paragraphStyles = {
marginBottom: 48,
}
const codeStyles = {
color: "#8A6534",
padding: 4,
backgroundColor: "#FFF4DB",
fontSize: "1.25rem",
borderRadius: 4,
}
const listStyles = {
marginBottom: 96,
paddingLeft: 0,
}
const listItemStyles = {
fontWeight: "300",
fontSize: "24px",
maxWidth: "560px",
}
const linkStyle = {
color: "#8954A8",
fontWeight: "bold",
fontSize: "16px",
verticalAlign: "5%",
}
const docLinkStyle = {
...linkStyle,
listStyleType: "none",
marginBottom: 24,
}
const descriptionStyle = {
color: "#232129",
fontSize: "14px",
}
const docLink = {
text: "Documentation",
url: "https://www.gatsbyjs.com/docs/",
color: "#8954A8",
}
// data
const links = [
{
text: "Tutorial",
url: "https://www.gatsbyjs.com/docs/tutorial/",
description:
"A great place to get started if you're new to web development. Designed to guide you through setting up your first Gatsby site.",
color: "#E95800",
},
{
text: "How to Guides",
url: "https://www.gatsbyjs.com/docs/how-to/",
description:
"Practical step-by-step guides to help you achieve a specific goal. Most useful when you're trying to get something done.",
color: "#1099A8",
},
{
text: "Reference Guides",
url: "https://www.gatsbyjs.com/docs/reference/",
description:
"Nitty-gritty technical descriptions of how Gatsby works. Most useful when you need detailed information about Gatsby's APIs.",
color: "#BC027F",
},
{
text: "Conceptual Guides",
url: "https://www.gatsbyjs.com/docs/conceptual/",
description:
"Big-picture explanations of higher-level Gatsby concepts. Most useful for building understanding of a particular topic.",
color: "#0D96F2",
},
{
text: "Plugin Library",
url: "https://www.gatsbyjs.com/plugins",
description:
"Add functionality and customize your Gatsby site or app with thousands of plugins built by our amazing developer community.",
color: "#000000",
},
]
// markup
const IndexPage = () => {
return (
<div>
{/* Reszta komponentów aplikacji */}
</div>
);
};
return (
<main style={pageStyles}>
<title>Home Page</title>
<h1 style={headingStyles}>
Congratulations
<br />
<span style={headingAccentStyles}> you just made a Gatsby site! </span>
<span role="img" aria-label="Party popper emojis">
🎉🎉🎉
</span>
</h1>
<p style={paragraphStyles}>
Edit <code style={codeStyles}>src/pages/index.js</code> to see this page
update in real-time.{" "}
<span role="img" aria-label="Sunglasses smiley emoji">
😎
</span>
</p>
<ul style={listStyles}>
<li style={docLinkStyle}>
<a
style={linkStyle}
href={`${docLink.url}?utm_source=starter&utm_medium=start-page&utm_campaign=minimal-starter`}
>
{docLink.text}
</a>
</li>
{links.map(link => (
<li key={link.url} style={{ ...listItemStyles, color: link.color }}>
<span>
<a
style={linkStyle}
href={`${link.url}?utm_source=starter&utm_medium=start-page&utm_campaign=minimal-starter`}
>
{link.text}
</a>
<p style={descriptionStyle}>{link.description}</p>
</span>
</li>
))}
</ul>
<img
alt="Gatsby G Logo"
src="data:image/svg+xml,%3Csvg width='24' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 2a10 10 0 110 20 10 10 0 010-20zm0 2c-3.73 0-6.86 2.55-7.75 6L14 19.75c3.45-.89 6-4.02 6-7.75h-5.25v1.5h3.45a6.37 6.37 0 01-3.89 4.44L6.06 9.69C7 7.31 9.3 5.63 12 5.63c2.13 0 4 1.04 5.18 2.65l1.23-1.06A7.959 7.959 0 0012 4zm-8 8a8 8 0 008 8c.04 0 .09 0-8-8z' fill='%23639'/%3E%3C/svg%3E"
/>
</main>
)
}
export default IndexPage;
export default IndexPage

View File

@ -1,92 +0,0 @@
import React from 'react';
import '../styles/general.scss';
import UserRegisterForm from '../components/forms/user_auth/userRegister.js';
import FootComponent from '../components/foot.js';
import NavBarComponent from '../components/navbar.js';
const LandingPage = () => {
return (
<>
<NavBarComponent />
<div className="landing-container">
<header className="landing">
<h2>Affordable. Efficient. Accessible.</h2>
<h1>GUARANTED.</h1>
<p>
Minimize your expenses without compromising on quality.
<br />
Our platform is built for individuals who need top-tier rendering
<br />
<span className="span-white">
without the top-tier investment.
</span>
</p>
<button>
GET A DEMO
</button>
<h4>
GPU IS IMPORTANT...
</h4>
<p>
...But <span className="span-white">GPU server can be very expensive.</span>
<br />
Configuration and administration<span className="span-white"> take too long time.</span>
<br />
<span className="span-white">
Everything of that needs so much additional knowledge.
</span>
</p>
<h2>
We Offer Ready Solution.
</h2>
<p>
Boost your GPU power for your 3D and AI models stuff
<br />
<span className="span-white">
without overpay for servers...
</span>
<br />
<span className="span-white">
...without overtime for environment adjustments!
</span>
</p>
<h2>
"OK... So What Makes You So Different?"
</h2>
<h4>
GUARANTED
</h4>
<p>
We only win if you win. You won't carry all the risk, we'll share it
</p>
<h4>
RESLUTS
</h4>
<p>
Our first priority is to get you results.
</p>
<h4>
LOCAL
</h4>
<p>
</p>
<h4>
SPECIALIZED
</h4>
<p>
</p>
</header>
<main className="secondary-content">
<UserRegisterForm />
</main>
</div>
<FootComponent />
</>
)
}
export default LandingPage

View File

@ -1,100 +0,0 @@
import { createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
const API_URL = process.env.REACT_APP_API_URL || 'http://localhost:8000';
// Helper function to get auth header
const getAuthHeader = (token) => ({
headers: { Authorization: `Bearer ${token}` }
});
export const fetchAiModels = createAsyncThunk(
'aiModelCrud/fetchModels',
async (_, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.get(`${API_URL}/ai/models`, getAuthHeader(token));
return response.data;
}
);
export const fetchAiModel = createAsyncThunk(
'aiModelCrud/fetchModel',
async (modelId, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.get(`${API_URL}/ai/models/${modelId}`, getAuthHeader(token));
return response.data;
}
);
export const createAiModel = createAsyncThunk(
'aiModelCrud/createModel',
async (modelData, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.post(`${API_URL}/ai/models`, modelData, getAuthHeader(token));
return response.data;
}
);
export const updateAiModel = createAsyncThunk(
'aiModelCrud/updateModel',
async ({ modelId, updates }, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.put(`${API_URL}/ai/models/${modelId}`, updates, getAuthHeader(token));
return response.data;
}
);
export const deleteAiModel = createAsyncThunk(
'aiModelCrud/deleteModel',
async (modelId, { getState }) => {
const { token } = getState().userAuth;
await axios.delete(`${API_URL}/ai/models/${modelId}`, getAuthHeader(token));
return modelId;
}
);
export const fetchAiTasks = createAsyncThunk(
'aiModelCrud/fetchTasks',
async ({ status, page = 1, limit = 10 }, { getState }) => {
const { token } = getState().userAuth;
const params = { page, limit };
if (status) params.status = status;
const response = await axios.get(`${API_URL}/ai/tasks`, {
...getAuthHeader(token),
params
});
return response.data;
}
);
export const createAiTask = createAsyncThunk(
'aiModelCrud/createTask',
async (taskData, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.post(`${API_URL}/ai/tasks`, taskData, getAuthHeader(token));
return response.data;
}
);
export const updateAiTask = createAsyncThunk(
'aiModelCrud/updateTask',
async ({ taskId, action }, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.put(
`${API_URL}/ai/tasks/${taskId}`,
{ action },
getAuthHeader(token)
);
return response.data;
}
);
export const deleteAiTask = createAsyncThunk(
'aiModelCrud/deleteTask',
async (taskId, { getState }) => {
const { token } = getState().userAuth;
await axios.delete(`${API_URL}/ai/tasks/${taskId}`, getAuthHeader(token));
return taskId;
}
);

View File

@ -1,94 +0,0 @@
import { createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
const API_URL = process.env.REACT_APP_API_URL || 'http://localhost:8000';
// Helper function to get auth header
const getAuthHeader = (token) => ({
headers: { Authorization: `Bearer ${token}` }
});
export const fetchRenders = createAsyncThunk(
'renderCrud/fetchRenders',
async ({ page = 1, limit = 10 }, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.get(`${API_URL}/renders`, {
...getAuthHeader(token),
params: { page, limit }
});
return response.data;
}
);
export const fetchRender = createAsyncThunk(
'renderCrud/fetchRender',
async (renderId, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.get(`${API_URL}/renders/${renderId}`, getAuthHeader(token));
return response.data;
}
);
export const updateRender = createAsyncThunk(
'renderCrud/updateRender',
async ({ renderId, updates }, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.put(`${API_URL}/renders/${renderId}`, updates, getAuthHeader(token));
return response.data;
}
);
export const deleteRender = createAsyncThunk(
'renderCrud/deleteRender',
async (renderId, { getState }) => {
const { token } = getState().userAuth;
await axios.delete(`${API_URL}/renders/${renderId}`, getAuthHeader(token));
return renderId;
}
);
export const fetchRenderTasks = createAsyncThunk(
'renderCrud/fetchTasks',
async ({ status, page = 1, limit = 10 }, { getState }) => {
const { token } = getState().userAuth;
const params = { page, limit };
if (status) params.status = status;
const response = await axios.get(`${API_URL}/renders/tasks`, {
...getAuthHeader(token),
params
});
return response.data;
}
);
export const createRenderTask = createAsyncThunk(
'renderCrud/createTask',
async (taskData, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.post(`${API_URL}/renders/tasks`, taskData, getAuthHeader(token));
return response.data;
}
);
export const updateRenderTask = createAsyncThunk(
'renderCrud/updateTask',
async ({ taskId, action }, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.put(
`${API_URL}/renders/tasks/${taskId}`,
{ action },
getAuthHeader(token)
);
return response.data;
}
);
export const deleteRenderTask = createAsyncThunk(
'renderCrud/deleteTask',
async (taskId, { getState }) => {
const { token } = getState().userAuth;
await axios.delete(`${API_URL}/renders/tasks/${taskId}`, getAuthHeader(token));
return taskId;
}
);

View File

@ -1,72 +0,0 @@
import { createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
const API_URL = process.env.REACT_APP_API_URL || 'http://localhost:8000';
// Helper function to get auth header
const getAuthHeader = (token) => ({
headers: { Authorization: `Bearer ${token}` }
});
export const fetchModels = createAsyncThunk(
'threeDModelCrud/fetchModels',
async (_, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.get(`${API_URL}/models`, getAuthHeader(token));
return response.data;
}
);
export const fetchModel = createAsyncThunk(
'threeDModelCrud/fetchModel',
async (modelId, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.get(`${API_URL}/models/${modelId}`, getAuthHeader(token));
return response.data;
}
);
export const createModel = createAsyncThunk(
'threeDModelCrud/createModel',
async (modelData, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.post(`${API_URL}/models`, modelData, getAuthHeader(token));
return response.data;
}
);
export const updateModel = createAsyncThunk(
'threeDModelCrud/updateModel',
async ({ modelId, updates }, { getState }) => {
const { token } = getState().userAuth;
const response = await axios.put(`${API_URL}/models/${modelId}`, updates, getAuthHeader(token));
return response.data;
}
);
export const deleteModel = createAsyncThunk(
'threeDModelCrud/deleteModel',
async (modelId, { getState }) => {
const { token } = getState().userAuth;
await axios.delete(`${API_URL}/models/${modelId}`, getAuthHeader(token));
return modelId;
}
);
export const uploadModel = createAsyncThunk(
'threeDModelCrud/uploadModel',
async ({ user_id, file, token }) => {
const formData = new FormData();
formData.append('user_id', user_id);
formData.append('file', file);
formData.append('token', token);
const response = await axios.post(`${API_URL}/models/upload`, formData, {
headers: {
'Content-Type': 'multipart/form-data',
Authorization: `Bearer ${token}`
}
});
return response.data;
}
);

View File

@ -1,179 +0,0 @@
import { createAsyncThunk } from '@reduxjs/toolkit';
import { setCredentials, setLoading, setError, logout } from '../slices/userAuthSlice';
import { API_URL, AUTH_CONFIG } from '../../config';
import { cookieService } from '../../services/cookieService';
export const loginUser = createAsyncThunk(
'userAuth/login',
async (credentials, { dispatch }) => {
try {
dispatch(setLoading(true));
const response = await fetch(`${API_URL}/auth/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(credentials),
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || 'Błąd logowania');
}
dispatch(setCredentials({
user: data.user,
token: data.token,
permissions: data.permissions
}));
return data;
} catch (error) {
dispatch(setError(error.message));
throw error;
} finally {
dispatch(setLoading(false));
}
}
);
export const registerUser = createAsyncThunk(
'userAuth/register',
async (userData, { dispatch }) => {
try {
dispatch(setLoading(true));
const response = await fetch(`${API_URL}/auth/register`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData),
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || 'Błąd rejestracji');
}
dispatch(setCredentials({
user: data.user,
token: data.token,
permissions: data.permissions
}));
return data;
} catch (error) {
dispatch(setError(error.message));
throw error;
} finally {
dispatch(setLoading(false));
}
}
);
export const logoutUser = createAsyncThunk(
'userAuth/logout',
async (_, { dispatch }) => {
try {
dispatch(setLoading(true));
const token = cookieService.getToken();
if (token) {
await fetch(`${API_URL}/auth/logout`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
},
});
}
dispatch(logout());
} catch (error) {
console.error('Błąd podczas wylogowywania:', error);
} finally {
dispatch(setLoading(false));
}
}
);
export const checkAuth = createAsyncThunk(
'userAuth/checkAuth',
async (_, { dispatch }) => {
try {
const token = cookieService.getToken();
if (!token) {
throw new Error('Brak tokenu');
}
const response = await fetch(`${API_URL}/auth/verify`, {
headers: {
'Authorization': `Bearer ${token}`,
},
});
if (!response.ok) {
throw new Error('Token nieprawidłowy');
}
const data = await response.json();
return data;
} catch (error) {
dispatch(logout());
throw error;
}
}
);
export const changePassword = createAsyncThunk(
'userAuth/changePassword',
async (passwordData) => {
const response = await fetch(`${API_URL}/change-password`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(passwordData),
});
return response.data;
}
);
export const updateProfile = createAsyncThunk(
'userAuth/updateProfile',
async (profileData, { rejectWithValue }) => {
try {
const response = await fetch(`${API_URL}/user/profile`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${cookieService.getToken()}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(profileData),
});
return response.data;
} catch (error) {
return rejectWithValue(error.response?.data);
}
}
);
export const deleteAccount = createAsyncThunk(
'userAuth/deleteAccount',
async (_, { rejectWithValue }) => {
try {
const response = await fetch(`${API_URL}/user/delete`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${cookieService.getToken()}`,
},
});
cookieService.clearAll();
return response.data;
} catch (error) {
return rejectWithValue(error.response?.data);
}
}
);

View File

@ -1,170 +0,0 @@
import { createSlice } from '@reduxjs/toolkit';
import {
fetchAiModels,
fetchAiModel,
createAiModel,
updateAiModel,
deleteAiModel,
createAiTask,
updateAiTask,
deleteAiTask,
fetchAiTasks
} from '../asyncThunks/aiModelCrudAsyncThunk';
const initialState = {
models: [],
selectedModel: null,
tasks: [],
isLoading: false,
error: null
};
const aiModelCrudSlice = createSlice({
name: 'aiModelCrud',
initialState,
reducers: {
clearError: (state) => {
state.error = null;
},
setSelectedModel: (state, action) => {
state.selectedModel = action.payload;
}
},
extraReducers: (builder) => {
// Fetch Models
builder.addCase(fetchAiModels.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(fetchAiModels.fulfilled, (state, action) => {
state.isLoading = false;
state.models = action.payload;
});
builder.addCase(fetchAiModels.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Fetch Single Model
builder.addCase(fetchAiModel.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(fetchAiModel.fulfilled, (state, action) => {
state.isLoading = false;
state.selectedModel = action.payload;
});
builder.addCase(fetchAiModel.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Create Model
builder.addCase(createAiModel.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(createAiModel.fulfilled, (state, action) => {
state.isLoading = false;
state.models.push(action.payload);
});
builder.addCase(createAiModel.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Update Model
builder.addCase(updateAiModel.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(updateAiModel.fulfilled, (state, action) => {
state.isLoading = false;
const index = state.models.findIndex(model => model.id === action.payload.id);
if (index !== -1) {
state.models[index] = action.payload;
}
});
builder.addCase(updateAiModel.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Delete Model
builder.addCase(deleteAiModel.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(deleteAiModel.fulfilled, (state, action) => {
state.isLoading = false;
state.models = state.models.filter(model => model.id !== action.payload);
});
builder.addCase(deleteAiModel.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Fetch Tasks
builder.addCase(fetchAiTasks.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(fetchAiTasks.fulfilled, (state, action) => {
state.isLoading = false;
state.tasks = action.payload;
});
builder.addCase(fetchAiTasks.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Create Task
builder.addCase(createAiTask.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(createAiTask.fulfilled, (state, action) => {
state.isLoading = false;
state.tasks.push(action.payload);
});
builder.addCase(createAiTask.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Update Task
builder.addCase(updateAiTask.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(updateAiTask.fulfilled, (state, action) => {
state.isLoading = false;
const index = state.tasks.findIndex(task => task.id === action.payload.id);
if (index !== -1) {
state.tasks[index] = action.payload;
}
});
builder.addCase(updateAiTask.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Delete Task
builder.addCase(deleteAiTask.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(deleteAiTask.fulfilled, (state, action) => {
state.isLoading = false;
state.tasks = state.tasks.filter(task => task.id !== action.payload);
});
builder.addCase(deleteAiTask.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
}
});
export const { clearError, setSelectedModel } = aiModelCrudSlice.actions;
export const aiModelCrudSelector = (state) => state.aiModelCrud;
export default aiModelCrudSlice.reducer;

View File

@ -1,155 +0,0 @@
import { createSlice } from '@reduxjs/toolkit';
import {
fetchRenders,
fetchRender,
updateRender,
deleteRender,
fetchRenderTasks,
createRenderTask,
updateRenderTask,
deleteRenderTask
} from '../asyncThunks/renderCrudAsyncThunk';
const initialState = {
renders: [],
selectedRender: null,
tasks: [],
isLoading: false,
error: null
};
const renderCrudSlice = createSlice({
name: 'renderCrud',
initialState,
reducers: {
clearError: (state) => {
state.error = null;
},
setSelectedRender: (state, action) => {
state.selectedRender = action.payload;
}
},
extraReducers: (builder) => {
// Fetch Renders
builder.addCase(fetchRenders.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(fetchRenders.fulfilled, (state, action) => {
state.isLoading = false;
state.renders = action.payload;
});
builder.addCase(fetchRenders.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Fetch Single Render
builder.addCase(fetchRender.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(fetchRender.fulfilled, (state, action) => {
state.isLoading = false;
state.selectedRender = action.payload;
});
builder.addCase(fetchRender.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Update Render
builder.addCase(updateRender.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(updateRender.fulfilled, (state, action) => {
state.isLoading = false;
const index = state.renders.findIndex(render => render.id === action.payload.id);
if (index !== -1) {
state.renders[index] = action.payload;
}
});
builder.addCase(updateRender.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Delete Render
builder.addCase(deleteRender.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(deleteRender.fulfilled, (state, action) => {
state.isLoading = false;
state.renders = state.renders.filter(render => render.id !== action.payload);
});
builder.addCase(deleteRender.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Fetch Tasks
builder.addCase(fetchRenderTasks.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(fetchRenderTasks.fulfilled, (state, action) => {
state.isLoading = false;
state.tasks = action.payload;
});
builder.addCase(fetchRenderTasks.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Create Task
builder.addCase(createRenderTask.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(createRenderTask.fulfilled, (state, action) => {
state.isLoading = false;
state.tasks.push(action.payload);
});
builder.addCase(createRenderTask.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Update Task
builder.addCase(updateRenderTask.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(updateRenderTask.fulfilled, (state, action) => {
state.isLoading = false;
const index = state.tasks.findIndex(task => task.id === action.payload.id);
if (index !== -1) {
state.tasks[index] = action.payload;
}
});
builder.addCase(updateRenderTask.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Delete Task
builder.addCase(deleteRenderTask.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(deleteRenderTask.fulfilled, (state, action) => {
state.isLoading = false;
state.tasks = state.tasks.filter(task => task.id !== action.payload);
});
builder.addCase(deleteRenderTask.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
}
});
export const { clearError, setSelectedRender } = renderCrudSlice.actions;
export const renderCrudSelector = (state) => state.renderCrud;
export default renderCrudSlice.reducer;

View File

@ -1,124 +0,0 @@
import { createSlice } from '@reduxjs/toolkit';
import {
fetchModels,
fetchModel,
createModel,
updateModel,
deleteModel,
uploadModel
} from '../asyncThunks/threeDModelCrudAsyncThunk';
const initialState = {
models: [],
selectedModel: null,
isLoading: false,
error: null,
upload_blend_file_status: ''
};
const threeDModelCrudSlice = createSlice({
name: 'threeDModelCrud',
initialState,
reducers: {
clearError: (state) => {
state.error = null;
},
setSelectedModel: (state, action) => {
state.selectedModel = action.payload;
}
},
extraReducers: (builder) => {
// Fetch Models
builder.addCase(fetchModels.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(fetchModels.fulfilled, (state, action) => {
state.isLoading = false;
state.models = action.payload;
});
builder.addCase(fetchModels.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Fetch Single Model
builder.addCase(fetchModel.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(fetchModel.fulfilled, (state, action) => {
state.isLoading = false;
state.selectedModel = action.payload;
});
builder.addCase(fetchModel.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Create Model
builder.addCase(createModel.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(createModel.fulfilled, (state, action) => {
state.isLoading = false;
state.models.push(action.payload);
});
builder.addCase(createModel.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Update Model
builder.addCase(updateModel.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(updateModel.fulfilled, (state, action) => {
state.isLoading = false;
const index = state.models.findIndex(model => model.id === action.payload.id);
if (index !== -1) {
state.models[index] = action.payload;
}
});
builder.addCase(updateModel.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Delete Model
builder.addCase(deleteModel.pending, (state) => {
state.isLoading = true;
state.error = null;
});
builder.addCase(deleteModel.fulfilled, (state, action) => {
state.isLoading = false;
state.models = state.models.filter(model => model.id !== action.payload);
});
builder.addCase(deleteModel.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
});
// Upload Model
builder.addCase(uploadModel.pending, (state) => {
state.isLoading = true;
state.error = null;
state.upload_blend_file_status = 'uploading';
});
builder.addCase(uploadModel.fulfilled, (state, action) => {
state.isLoading = false;
state.upload_blend_file_status = { info: 'Upload successful' };
});
builder.addCase(uploadModel.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error.message;
state.upload_blend_file_status = { info: 'Upload failed' };
});
}
});
export const { clearError, setSelectedModel } = threeDModelCrudSlice.actions;
export const threeDModelCrudSelector = (state) => state.threeDModelCrud;
export default threeDModelCrudSlice.reducer;

View File

@ -1,54 +0,0 @@
import { createSlice } from '@reduxjs/toolkit';
import { cookieService } from '../../services/cookieService';
const initialState = {
user: cookieService.getUserData() || null,
token: cookieService.getToken() || null,
isAuthenticated: !!cookieService.getToken(),
loading: false,
error: null,
permissions: []
};
const userAuthSlice = createSlice({
name: 'userAuth',
initialState,
reducers: {
setCredentials: (state, { payload }) => {
const { user, token, permissions } = payload;
state.user = user;
state.token = token;
state.isAuthenticated = true;
state.permissions = permissions;
cookieService.setToken(token);
cookieService.setUserData({ ...user, permissions });
},
logout: (state) => {
state.user = null;
state.token = null;
state.isAuthenticated = false;
state.permissions = [];
cookieService.clearAll();
},
setLoading: (state, { payload }) => {
state.loading = payload;
},
setError: (state, { payload }) => {
state.error = payload;
},
clearError: (state) => {
state.error = null;
}
}
});
export const { setCredentials, logout, setLoading, setError, clearError } = userAuthSlice.actions;
export const selectCurrentUser = (state) => state.userAuth.user;
export const selectCurrentToken = (state) => state.userAuth.token;
export const selectIsAuthenticated = (state) => state.userAuth.isAuthenticated;
export const selectUserPermissions = (state) => state.userAuth.permissions;
export const selectAuthLoading = (state) => state.userAuth.loading;
export const selectAuthError = (state) => state.userAuth.error;
export default userAuthSlice.reducer;

View File

@ -1,14 +0,0 @@
import { configureStore } from '@reduxjs/toolkit';
import userAuthReducer from './slices/userAuthSlice';
import threeDModelCrudReducer from './slices/threeDModelCrudSlice';
import aiModelCrudReducer from './slices/aiModelCrudSlice';
import renderCrudReducer from './slices/renderCrudSlice';
export const store = configureStore({
reducer: {
userAuth: userAuthReducer,
threeDModelCrud: threeDModelCrudReducer,
aiModelCrud: aiModelCrudReducer,
renderCrud: renderCrudReducer
}
});

View File

@ -1,23 +0,0 @@
// src/services/api.js
import axios from 'axios';
import { getCookie } from './cookie';
const api = axios.create({
baseURL: 'http://0.0.0.0:9090',
withCredentials: true,
});
api.interceptors.request.use(
(config) => {
const token = getCookie('access_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
export default api;

View File

@ -1,35 +0,0 @@
// src/services/auth.service.js
import api from './api';
import { setCookie, eraseCookie } from './cookie';
class AuthService {
async login(username, password) {
// The FastAPI /auth endpoint expects form data: username, password
const formData = new FormData();
formData.append('username', username);
formData.append('password', password);
const response = await api.post('/auth', formData);
const { access_token } = response.data;
// Save to cookie
setCookie('access_token', access_token, 1); // 1 day (adjust as needed)
return response.data;
}
async register(username, password, email) {
const payload = { username, password, email };
return api.post('/register/', payload);
}
logout() {
// Remove token cookie
eraseCookie('access_token');
}
// Optionally, you can provide a check to see if cookie is present
isLoggedIn() {
return !!document.cookie.includes('access_token=');
}
}
export default new AuthService();

View File

@ -1,24 +0,0 @@
export function setCookie(name, value, days = 1) {
const date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
const expires = 'expires=' + date.toUTCString();
document.cookie = `${name}=${value};${expires};path=/;SameSite=Lax`;
}
export function getCookie(name) {
const nameEQ = name + '=';
const ca = document.cookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) === ' ') c = c.substring(1);
if (c.indexOf(nameEQ) === 0) {
return c.substring(nameEQ.length, c.length);
}
}
return null;
}
export function eraseCookie(name) {
document.cookie = name + '=; Max-Age=-99999999;path=/;';
}

View File

@ -1,46 +0,0 @@
import Cookies from 'js-cookie';
const TOKEN_COOKIE_NAME = 'auth_token';
const USER_COOKIE_NAME = 'user_data';
export const cookieService = {
setToken: (token) => {
Cookies.set(TOKEN_COOKIE_NAME, token, {
expires: 7, // 7 dni
secure: true, // tylko HTTPS
sameSite: 'strict', // ochrona przed CSRF
path: '/'
});
},
getToken: () => {
return Cookies.get(TOKEN_COOKIE_NAME);
},
removeToken: () => {
Cookies.remove(TOKEN_COOKIE_NAME, { path: '/' });
},
setUserData: (userData) => {
Cookies.set(USER_COOKIE_NAME, JSON.stringify(userData), {
expires: 7,
secure: true,
sameSite: 'strict',
path: '/'
});
},
getUserData: () => {
const userData = Cookies.get(USER_COOKIE_NAME);
return userData ? JSON.parse(userData) : null;
},
removeUserData: () => {
Cookies.remove(USER_COOKIE_NAME, { path: '/' });
},
clearAll: () => {
this.removeToken();
this.removeUserData();
}
};

View File

@ -1,72 +0,0 @@
// src/services/model.service.js
import api from './api';
/**
* Fetch a paginated list of models
*/
export async function getModels(page = 1, limit = 10) {
const res = await api.get('/models', { params: { page, limit } });
return res.data;
}
/**
* Create a new model:
* 1) Request a presigned URL from backend
* 2) PUT the file to S3
* 3) POST the model data with s3Key to backend
*/
export async function createModel(name, file) {
// get presigned URL from your backend
const presignRes = await api.post('/models/upload_url', { fileName: file.name });
const { url, key } = presignRes.data; // e.g. { url, key }
// upload file to S3
await fetch(url, {
method: 'PUT',
headers: { 'Content-Type': file.type },
body: file,
});
// call actual model creation
const createRes = await api.post('/models', {
name,
s3Key: key,
});
return createRes.data;
}
/**
* Update an existing model (similar approach)
*/
export async function updateModel(modelId, newName, newFile) {
let s3Key;
if (newFile) {
// 1) get presigned URL
const presignRes = await api.post('/models/upload_url', { fileName: newFile.name });
const { url, key } = presignRes.data;
// 2) PUT file to S3
await fetch(url, {
method: 'PUT',
headers: { 'Content-Type': newFile.type },
body: newFile,
});
s3Key = key;
}
// 3) call PUT /models/{id} with updated fields
const payload = {};
if (newName) payload.name = newName;
if (s3Key) payload.s3Key = s3Key;
const updateRes = await api.put(`/models/${modelId}`, payload);
return updateRes.data;
}
/**
* Delete model
*/
export async function deleteModel(modelId) {
const res = await api.delete(`/models/${modelId}`);
return res.data;
}

View File

@ -1,82 +0,0 @@
// src/services/task.service.js
import api from './api';
/**
* RENDER tasks
*/
// Return a list of tasks from the backend
export async function getRenderTasks(status, page = 1, limit = 10) {
const params = { page, limit };
if (status) params.status = status;
const res = await api.get('/renders/tasks', { params });
return res.data;
}
/**
* Create a render task (Photo or Video).
* The backend expects either `photo: {...}` or `video: {...}` in the request body
*/
export async function createRenderTaskPhoto(userId, modelId, renderName) {
const body = {
photo: { USER_ID: userId, MODEL_ID: modelId, RENDER_NAME: renderName },
};
const res = await api.post('/renders/tasks', body);
return res.data;
}
export async function createRenderTaskVideo(userId, modelId, renderName, frameStart, frameEnd) {
const body = {
video: {
USER_ID: userId,
MODEL_ID: modelId,
RENDER_NAME: renderName,
FRAME_START: frameStart,
FRAME_END: frameEnd,
},
};
const res = await api.post('/renders/tasks', body);
return res.data;
}
// Stop or resume a render task
export async function updateRenderTask(taskId, action) {
const res = await api.put(`/renders/tasks/${taskId}`, { action });
return res.data;
}
// Delete (stop) a render task
export async function deleteRenderTask(taskId) {
const res = await api.delete(`/renders/tasks/${taskId}`);
return res.data;
}
/**
* AI tasks
*/
export async function getAiTasks(status, page = 1, limit = 10) {
const params = { page, limit };
if (status) params.status = status;
const res = await api.get('/ai/tasks', { params });
return res.data;
}
export async function createAiTask(userId) {
// The backend expects { ai_model: { USER_ID: ... } }
const body = {
ai_model: { USER_ID: userId },
};
const res = await api.post('/ai/tasks', body);
return res.data;
}
export async function updateAiTask(taskId, action) {
const res = await api.put(`/ai/tasks/${taskId}`, { action });
return res.data;
}
export async function deleteAiTask(taskId) {
const res = await api.delete(`/ai/tasks/${taskId}`);
return res.data;
}

View File

@ -1,104 +0,0 @@
// Define common variables
$background-base-start: rgba(0, 90, 25, 1);
$background-base-end: rgb(51,54,51, 1);
$header-background: 0;
$form-background: rgba(0,0,0,0.5);
$header-color: $form-background;
$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: radial-gradient($background-base-start, $background-base-end 70%);
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
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,52 +0,0 @@
$cube-size: 350px;
$cube-color: rgba(0, 140, 0, 0.5);
$perspective: 100000px;
$animation-duration: 20s;
@mixin large-cube-face {
position: absolute;
width: $cube-size - 15px;
height: $cube-size - 15px;
background: $cube-color;
will-change: transform;
}
@keyframes rotateLargeCube {
0% {
transform: rotateX(0) rotateY(0) rotateZ(0);
}
100% {
transform: rotateX(360deg) rotateY(360deg) rotateZ(360deg);
}
}
.large-graphic-container {
width: 100%;
margin-top: 0%;
//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
}
.large-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: rotateLargeCube $animation-duration infinite linear;
will-change: transform;
div {
@include large-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

@ -1,56 +0,0 @@
$cube-size: 30px;
$cube-color: rgba(0, 140, 0, 0.5);
$perspective: 10000px;
$animation-duration: 20s;
@mixin cube-face {
position: absolute;
width: $cube-size - 4px;
height: $cube-size - 4px;
background: $cube-color;
}
@keyframes rotateCube {
0% {
transform: rotateX(0) rotateY(0) rotateZ(0);
}
100% {
transform: rotateX(360deg) rotateY(360deg) rotateZ(360deg);
}
}
.graphic-container {
display: flex;
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;
div {
@include cube-face;
}
.face-front { transform: translateZ($cube-size / 2); }
.face-back { transform: translateZ(-$cube-size / 2) rotateY(180deg); }
.face-right { transform: rotateY(90deg) translateZ($cube-size / 2); }
.face-left { transform: rotateY(-90deg) translateZ($cube-size / 2); }
.face-top { transform: rotateX(90deg) translateZ($cube-size / 2); }
.face-bottom { transform: rotateX(-90deg) translateZ($cube-size / 2); }
}
.title {
color: white;
font-size: 30px;
font-weight: 600;
margin-left: 10px;
}
}