123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- import Breadcrumb from "../components/Breadcrumbs";
- import {connect} from "react-redux";
- import {Avatar, Box, Button, Container, Grid, TextField, Typography, useMediaQuery} from "@mui/material";
- import Redirect from "react-router-dom/es/Redirect";
- import Tabs from "@mui/material/Tabs";
- import Tab from "@mui/material/Tab";
- import {createRef, useCallback, useEffect, useState} from "react";
- import PropTypes from "prop-types";
- import ManageAccountsIcon from '@mui/icons-material/ManageAccounts';
- import CancelIcon from '@mui/icons-material/Cancel';
- import SendAndArchiveIcon from '@mui/icons-material/SendAndArchive';
- import {actionAuthLogout} from "../reducers/AuthReducer";
- import {actionUserRemove} from "../reducers/UserReducer";
- import {backURL} from "../actions/PathDB";
- import {CMainOrders} from "./MyOrdersPage";
- import {CMainWishList} from "./WishListPage";
- import Dropzone, {useDropzone} from 'react-dropzone';
- import {
- actionFullUserUpdate,
- actionSetAvatar,
- actionSetLogin,
- actionSetNick, actionSetPassword,
- actionUploadFile
- } from "../actions/ActionUploadFile";
- import {actionFullUserFindOne} from "../actions/ActionUserFind";
- function TabPanel(props) {
- const { children, value, index, ...other } = props;
- return (
- <div
- role="tabpanel"
- hidden={value !== index}
- id={`vertical-tabpanel-${index}`}
- aria-labelledby={`vertical-tab-${index}`}
- style={{width: '100%'}}
- {...other}
- >
- {value === index && (
- <Box sx={{ p: 3}}>
- <Typography>{children}</Typography>
- </Box>
- )}
- </div>
- );
- }
- TabPanel.propTypes = {
- children: PropTypes.node,
- index: PropTypes.number.isRequired,
- value: PropTypes.number.isRequired,
- };
- function a11yProps(index) {
- return {
- id: `vertical-tab-${index}`,
- 'aria-controls': `vertical-tabpanel-${index}`,
- };
- }
- const ItemTabsAccountDefault = ({title, content}) => {
- const matches = useMediaQuery('(max-width:899px)')
- return(
- <Grid item xs={6} sm={4} marginBottom='20px'>
- <Typography
- color='#616161'
- fontWeight='300'
- marginBottom='5px'
- fontSize={matches ? '13px' : '16px'}
- >
- {title}
- </Typography>
- <Typography
- color='#000'
- fontWeight='400'
- fontSize={matches ? '16px' : '22px'}
- >
- {content}
- </Typography>
- </Grid>
- )
- }
- const MyDropzone = ({onLoad}) => {
- const [files, setFiles] = useState([]);
- const {getRootProps, getInputProps, isDragActive} = useDropzone({accept: 'image/*', onDrop: acceptedFiles => {
- setFiles(acceptedFiles.map(file => Object.assign(file, {
- preview: URL.createObjectURL(file)
- })));
- }})
- const thumbs = files.map(file => (
- <div key={file.name} style={{display: 'inline-flex', borderRadius: 2,border: '1px solid #eaeaea',marginBottom: 8, marginRight: 8, width: 500, height: 500, padding: 4, boxSizing: 'border-box'}}>
- <div style={{display: 'flex', minWidth: 0, overflow: 'hidden'}}>
- <img src={file.preview} style={{display: 'block', width: 'auto', height: '100%', objectFit: 'cover', objectPosition: 'center center'}} alt={'avatar'}/>
- </div>
- </div>
- ));
- useEffect(() => {
- files.forEach(file => URL.revokeObjectURL(file.preview));
- onLoad(files)
- }, [files]);
- return (
- <section style={{display: 'flex', flexDirection: 'column', justifyContent: 'space-between', alignItems: 'center', width:"100%", borderRadius: '20px', padding: '20px'}}>
- <div style={{width:"100%", height: "100%", border: '1px dashed #616161', borderRadius: '20px', padding: '20px'}} {...getRootProps()}>
- <input {...getInputProps()} />
- {isDragActive ?
- <Typography variant='body1' color='#616161'>Drop the file here ...</Typography> :
- <Typography variant='body1' color='#616161'>Drag 'n' drop image files here, or click to select file</Typography>
- }
- <aside>
- {thumbs}
- </aside>
- </div>
- </section>
- )
- }
- const FormUpload = ({user, setStatus, setLogin, setNick, setPassword, setImage}) => {
- const [loginValue, setLoginValue] = useState(user?.login || '')
- const [nickValue, setNickValue] = useState(user?.nick || '')
- const [passwordValue, setPasswordValue] = useState('')
- const [fileValue, setFileValue] = useState('')
- return (
- <Grid container spacing={2} justifyContent={'center'} textAlign='center' flexDirection='column'>
- <Grid item xs={12} display='flex' justifyContent='space-between' alignItems='center' marginBottom='30px'>
- <TextField sx={{color: '#000'}} label={'Login'} variant="outlined" placeholder={user?.login || ''} onChange={e => setLoginValue(e.target.value)}/>
- <TextField sx={{color: '#000'}} label={'Nick'} variant="outlined" placeholder={user?.nick || ''} onChange={e => setNickValue(e.target.value)}/>
- <TextField sx={{color: '#000'}} label={'Password'} type='password' variant="outlined" onChange={e => setPasswordValue(e.target.value)}/>
- </Grid>
- <Grid item xs={12} display='flex' justifyContent='space-between' alignItems='center' marginBottom='30px'>
- <MyDropzone onLoad={value => setFileValue(value)}/>
- </Grid>
- <Grid item xs={12} display='flex' justifyContent='center' alignItems='center'>
- <Button
- style={{ color: '#1976d2'}}
- fullWidth
- type='submit'
- onClick={() => {
- if (loginValue !== user?.login) {
- setLogin(loginValue)
- }
- if (nickValue !== user?.nick) {
- setNick(nickValue)
- }
- if (passwordValue){
- setPassword(passwordValue)
- }
- if (Array.isArray(fileValue) && fileValue[0]) {
- setImage(fileValue[0]);
- }
- setStatus(false)
- }}
- >
- <SendAndArchiveIcon style={{marginRight: '5px'}}/>
- Save
- </Button>
- <Button
- style={{ color: '#1976d2'}}
- fullWidth
- onClick={() => setStatus(false)}
- >
- <CancelIcon style={{marginRight: '5px'}}/>
- Cancel
- </Button>
- </Grid>
- </Grid>
- )
- }
- const CFormUpload = connect(null, {setLogin: actionSetLogin, setNick: actionSetNick, setPassword: actionSetPassword, setImage: actionSetAvatar, userUpdate: actionFullUserFindOne})(FormUpload)
- const AccountDetails = ({promise, user, time}) => {
- const [status, setStatus] = useState(false)
- return (
- !status ?
- <Grid container spacing={2} justifyContent={'space-between'} alignItems={'center'} textAlign={'center'}>
- <ItemTabsAccountDefault title={'Login'} content={user?.login}/>
- <ItemTabsAccountDefault title={'Nick'} content={user?.nick}/>
- <ItemTabsAccountDefault title={'Status account'} content={user?.acl[2] || user?.acl[1]}/>
- <ItemTabsAccountDefault title={'Account creation date'} content={time}/>
- <ItemTabsAccountDefault title={'Avatar'}
- content={
- (user?.avatar?.url ? <Avatar style={{margin: '0 auto'}} alt="User" src={backURL + '/' + user?.avatar?.url}/> : 'Not installed')
- }
- />
- <Grid item xs={12} md={4}>
- <Typography
- sx={{cursor: 'pointer'}}
- color={'#1976d2'}
- display='flex'
- justifyContent='center'
- alignItems='center'
- variant='h6'
- onClick={() => setStatus(true)}
- >
- <ManageAccountsIcon style={{marginRight: '10px'}}/>
- Edit data
- </Typography>
- </Grid>
- {!promise.setNewLogin?.payload && promise.setNewLogin?.status === 'RESOLVED' && <Typography width='100%' textAlign='center' color='red'>this login already exists</Typography>}
- </Grid> :
- <CFormUpload user={user} setStatus={value => setStatus(value)}/>
- )
- }
- const ProfilePage = ({user = {}, promise, authLogOut, userLogOut}) => {
- const matches = useMediaQuery('(max-width:899px)')
- const matches2 = useMediaQuery('(max-width:768px)')
- const [value, setValue] = useState(0)
- const handleChange = (event, newValue) => {
- setValue(newValue);
- };
- let formattedTime = 0;
- if (Object.keys(user).length !== 0) {
- let date = new Date(+user.createdAt);
- let year = date.getFullYear();
- let month = "0" + (date.getMonth()+1);
- let day = "0" + date.getDate();
- let hours = "0" + date.getHours();
- let minutes = "0" + date.getMinutes();
- let seconds = "0" + date.getSeconds();
- formattedTime = day.substr(-2) + '.' + month.substr(-2) + '.' + year +
- ' ' + hours.substr(-2) + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
- }
- return (
- Object.keys(user).length > 1 &&
- <>
- <Breadcrumb links={['Profile']}/>
- <main style={{backgroundColor: "#f3f3f3", padding: matches ? "20px 0" : "50px 0"}}>
- <Container maxWidth="lg">
- <Box>
- <Typography
- variant='h5'
- textAlign='center'
- fontFamily='sarif'
- marginBottom={matches ? '20px':'40px'}
- >
- LOGGED IN AS <strong>{user.login.toUpperCase()}</strong>
- </Typography>
- </Box>
- <Box
- sx={{ flexGrow: 1, bgcolor: '#fff', display: 'flex', height: '100%', alignItems: 'center'}}
- flexDirection={matches2 ? 'column': "row"}
- >
- <Tabs
- orientation={matches2 ? 'horizontal': "vertical"}
- variant="scrollable"
- value={value}
- onChange={handleChange}
- aria-label="Profile settings"
- sx={{ borderRight: 1, borderColor: 'divider', padding: '50px 0', height: '100%'}}
- >
- <Tab sx={{padding: '0 50px', textAlign: 'center'}} label={'ACCOUNT DETAILS'} {...a11yProps(0)} />
- <Tab sx={{padding: '0 50px', textAlign: 'center'}} label={'my orders'} {...a11yProps(1)} />
- <Tab sx={{padding: '0 50px', textAlign: 'center'}} label={'wish list'} {...a11yProps(2)} />
- <Button onClick={() => {authLogOut(); userLogOut()}}>Logout</Button>
- </Tabs>
- <TabPanel value={value} index={0}>
- <AccountDetails user={user} promise={promise} time={formattedTime}/>
- </TabPanel>
- <TabPanel value={value} index={1}>
- <CMainOrders itemsPerPage={5}/>
- </TabPanel>
- <TabPanel value={value} index={2}>
- <CMainWishList color={'#fff'}/>
- </TabPanel>
- </Box>
- </Container>
- </main>
- </>
- )
- }
- const CProfilePage = connect(state => ({user: state.user, promise: state.promise}), {authLogOut: actionAuthLogout, userLogOut: actionUserRemove})(ProfilePage)
- export default CProfilePage
|