feat: shop builder

This commit is contained in:
Damien Ostler 2024-02-18 06:59:55 -05:00
parent 539e1607bd
commit 565cb5dffb
18 changed files with 638 additions and 393 deletions

View File

@ -22,7 +22,8 @@ const ArtistPortfolio = ({masonry,columns,artistId}) => {
<Typography variant="h4" sx={{textAlign:"center"}}>
Loading
</Typography>
<CircularProgress sx={{paddingTop:5}} />
<Box sx={{paddingTop:"2%"}}/>
<CircularProgress />
</Box>
) :
(

View File

@ -1,16 +1,21 @@
import * as React from 'react';
import { ImageList, Box, Button, CircularProgress } from '@mui/material';
import { ImageList, Box, Button, CircularProgress, Slider } from '@mui/material';
import { useEffect, useState } from "react";
import EditableArtistPortfolioImage from './editableArtistPortfolioImage';
import FileOpenIcon from '@mui/icons-material/FileOpen';
import { Grid } from '@mui/material';
const EditableArtistPortfolio = ({ artistId }) => {
const [portfolioData, setPortfolioData] = useState([]);
const [columns, setColumns] = useState(2);
const [loading, setLoading] = useState(true); // State for loading indicator
useEffect(() => {
getData();
}, []);
const handleColumns = (event, value)=>{
setColumns(value);
}
const getData = async () => {
const response = await fetch('/api/discovery/artist/' + artistId + '/portfolio');
const data = await response.json();
@ -46,29 +51,40 @@ const EditableArtistPortfolio = ({ artistId }) => {
(
<Grid container spacing={2} sm={12}>
<Grid item xs={12} sm={12} sx={{ textAlign: "center" }}>
<input
id="portfolioUploadInput"
style={{ display: 'none' }}
accept="image/*"
type="file"
onChange={handlePortfolioUploadImageChange}
/>
<label htmlFor="portfolioUploadInput">
<Button
fullWidth
variant='outlined'
component="span"
size="large"
sx={{width:"100%"}}
startIcon={<FileOpenIcon />}
>
{(portfolioData.length > 0 ? "Upload Another Portfolio Image" : "Upload Your First Portfolio Image")}
</Button>
</label>
</Grid>
<Grid item xs={12} sm={12} sx={{ textAlign: "center" }}>
<input
id="portfolioUploadInput"
style={{ display: 'none' }}
accept="image/*"
type="file"
onChange={handlePortfolioUploadImageChange}
/>
<label htmlFor="portfolioUploadInput">
<Button
fullWidth
variant='outlined'
component="span"
size="small"
sx={{width:"100%"}}
startIcon={<FileOpenIcon />}
>
{(portfolioData.length > 0 ? "Upload Another Portfolio Image" : "Upload Your First Portfolio Image")}
</Button>
</label>
<Slider
defaultValue={columns}
aria-labelledby="discrete-slider"
valueLabelDisplay="auto"
onChange={handleColumns}
step={1}
marks
min={1}
max={5}/>
</Grid>
<Grid item xs={12} sm={12}>
<ImageList cols={2} rowHeight={200} sx={{ height: 400, width:"100%" }}>
<Grid item xs={12} sm={12} sx={{maxHeight:"45rem",overflowY:"scroll"}}>
<ImageList variant='masonry' cols={columns} sx={{ width:"100%" }}>
{portfolioData.map((item) => (
<EditableArtistPortfolioImage artistId={artistId} itemId={item.id} reload={getData}/>
))}

View File

@ -27,7 +27,7 @@ const EditableArtistPortfolioImage = ({artistId,itemId,reload}) => {
}
return (
<ImageListItem key={itemId } sx={{maxWidth:300, maxHeight:300, overflow:"hidden"}}>
<ImageListItem key={itemId } >
<img
srcSet={process.env.NEXT_PUBLIC_API_URL+`/api/Discovery/Sellers/${artistId}/Portfolio/${itemId}`}
src={process.env.NEXT_PUBLIC_API_URL+`/api/Discovery/Sellers/${artistId}/Portfolio/${itemId}`}

View File

@ -7,7 +7,7 @@ const columns: GridColDef[] = [
{ field: 'artist', headerName: 'Artist', width: 130 },
{ field: 'status', headerName: 'Status', width: 130 },
{ field: 'action', headerName: 'Action', width: 180, renderCell: (params) => {
return (<Button variant="outlined" color="primary" fullWidth>View More</Button>);
return (<Button variant="outlined" color="secondary" fullWidth>View More</Button>);
}},
];

116
components/SellerStats.tsx Normal file
View File

@ -0,0 +1,116 @@
// ** React Imports
import { ReactElement } from 'react'
// ** MUI Imports
import Box from '@mui/material/Box'
import Grid from '@mui/material/Grid'
import Card from '@mui/material/Card'
import Avatar from '@mui/material/Avatar'
import CardHeader from '@mui/material/CardHeader'
import IconButton from '@mui/material/IconButton'
import Typography from '@mui/material/Typography'
import CardContent from '@mui/material/CardContent'
// ** Icons Imports
import TrendingUp from 'mdi-material-ui/TrendingUp'
import CurrencyUsd from 'mdi-material-ui/CurrencyUsd'
import DotsVertical from 'mdi-material-ui/DotsVertical'
import CellphoneLink from 'mdi-material-ui/CellphoneLink'
import AccountOutline from 'mdi-material-ui/AccountOutline'
import CompareArrowsIcon from '@mui/icons-material/CompareArrows';
// ** Types
import { ThemeColor } from '../core/layouts/types'
import { Person } from '@mui/icons-material'
interface DataType {
stats: string
title: string
color: ThemeColor
icon: ReactElement
}
const salesData: DataType[] = [
{
stats: '0',
title: 'Customers',
color: 'primary',
icon: <Person sx={{ fontSize: '1.75rem' }} />
},
{
stats: '0',
title: 'Accepted',
color: 'success',
icon: <CompareArrowsIcon sx={{ fontSize: '1.75rem' }} />
},
{
stats: '0',
color: 'warning',
title: 'Denied',
icon: <CompareArrowsIcon sx={{ fontSize: '1.75rem' }} />
},
{
stats: '$0.00',
color: 'info',
title: 'Revenue',
icon: <CurrencyUsd sx={{ fontSize: '1.75rem' }} />
}
]
const renderStats = () => {
return salesData.map((item: DataType, index: number) => (
<Grid item xs={12} sm={3} key={index}>
<Box key={index} sx={{ display: 'flex', alignItems: 'center' }}>
<Avatar
variant='rounded'
sx={{
mr: 3,
width: 44,
height: 44,
boxShadow: 3,
color: 'common.white',
backgroundColor: `${item.color}.main`
}}
>
{item.icon}
</Avatar>
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
<Typography variant='caption'>{item.title}</Typography>
<Typography variant='h6'>{item.stats}</Typography>
</Box>
</Box>
</Grid>
))
}
const SellerStats = () => {
return (
<Card>
<CardHeader
title='Seller Statistics'
subheader={
<Typography variant='body2'>
<Box component='span' sx={{ fontWeight: 600, color: 'text.primary' }}>
Total 0% growth
</Box>{' '}
😎 this month
</Typography>
}
titleTypographyProps={{
sx: {
mb: 2.5,
lineHeight: '2rem !important',
letterSpacing: '0.15px !important'
}
}}
/>
<CardContent sx={{ pt: theme => `${theme.spacing(3)} !important` }}>
<Grid container spacing={[5, 0]}>
{renderStats()}
</Grid>
</CardContent>
</Card>
)
}
export default SellerStats

View File

@ -1,5 +1,5 @@
// ** React Imports
import { useState, SyntheticEvent, Fragment } from 'react'
import { useState, SyntheticEvent, Fragment, useEffect } from 'react'
// ** Next Import
import { useRouter } from 'next/router'
@ -37,6 +37,17 @@ const BadgeContentSpan = styled('span')(({ theme }) => ({
const UserDropdown = () => {
const { user, isLoading } = useUser();
const [appUser, setAppUser] = useState(null);
useEffect(() => {
getData()
}, []);
const getData = async () => {
var userResponse = await fetch('/api/me');
var user = await userResponse.json();
setAppUser(user);
}
// ** States
const [anchorEl, setAnchorEl] = useState<Element | null>(null)
@ -69,7 +80,7 @@ const UserDropdown = () => {
}
return (
(!isLoading && user) ? (
(!isLoading && user && appUser) ? (
<Fragment>
<Badge
overlap='circular'
@ -100,10 +111,10 @@ const UserDropdown = () => {
badgeContent={<BadgeContentSpan />}
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
>
<Avatar alt={user.nickname} src={user.picture} sx={{ width: '2.5rem', height: '2.5rem' }} />
<Avatar alt={appUser["displayName"]} src={user.picture} sx={{ width: '2.5rem', height: '2.5rem' }} />
</Badge>
<Box sx={{ display: 'flex', marginLeft: 3, alignItems: 'flex-start', flexDirection: 'column' }}>
<Typography sx={{ fontWeight: 600 }}>{user.nickname}</Typography>
<Typography sx={{ fontWeight: 600 }}>{appUser["displayName"]}</Typography>
<Typography variant='body2' sx={{ fontSize: '0.8rem', color: 'text.disabled' }}>
Welcome back!
</Typography>
@ -111,43 +122,12 @@ const UserDropdown = () => {
</Box>
</Box>
<Divider sx={{ mt: 0, mb: 1 }} />
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
<Box sx={styles}>
<AccountOutline sx={{ marginRight: 2 }} />
Profile
</Box>
</MenuItem>
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
<Box sx={styles}>
<EmailOutline sx={{ marginRight: 2 }} />
Inbox
</Box>
</MenuItem>
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
<Box sx={styles}>
<MessageOutline sx={{ marginRight: 2 }} />
Chat
</Box>
</MenuItem>
<Divider />
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
<MenuItem sx={{ p: 0 }} onClick={() => router.push("/dashboard/settings")}>
<Box sx={styles}>
<CogOutline sx={{ marginRight: 2 }} />
Settings
</Box>
</MenuItem>
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
<Box sx={styles}>
<CurrencyUsd sx={{ marginRight: 2 }} />
Pricing
</Box>
</MenuItem>
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
<Box sx={styles}>
<HelpCircleOutline sx={{ marginRight: 2 }} />
FAQ
</Box>
</MenuItem>
<Divider />
<MenuItem sx={{ py: 2 }} onClick={() => handleDropdownClose('/api/auth/logout')}>
<LogoutVariant sx={{ marginRight: 2, fontSize: '1.375rem', color: 'text.secondary' }} />

View File

@ -50,20 +50,8 @@ const AppBarContent = (props: Props) => {
<Menu />
</IconButton>
) : null}
<TextField
size='small'
sx={{ '& .MuiOutlinedInput-root': { borderRadius: 4 } }}
InputProps={{
startAdornment: (
<InputAdornment position='start'>
<Magnify fontSize='small' />
</InputAdornment>
)
}}
/>
</Box>
<Box className='actions-right' sx={{ display: 'flex', alignItems: 'center' }}>
<ModeToggler settings={settings} saveSettings={saveSettings} />
<NovuProvider subscriberId={'on-boarding-subscriber-id-123'} applicationIdentifier={'9SKjzgN_odAF'}>
<PopoverNotificationCenter colorScheme={'light'}>

View File

@ -3,12 +3,7 @@ import Login from 'mdi-material-ui/Login'
import Table from 'mdi-material-ui/Table'
import CubeOutline from 'mdi-material-ui/CubeOutline'
import HomeOutline from 'mdi-material-ui/HomeOutline'
import FormatLetterCase from 'mdi-material-ui/FormatLetterCase'
import AccountCogOutline from 'mdi-material-ui/AccountCogOutline'
import CreditCardOutline from 'mdi-material-ui/CreditCardOutline'
import AccountPlusOutline from 'mdi-material-ui/AccountPlusOutline'
import AlertCircleOutline from 'mdi-material-ui/AlertCircleOutline'
import GoogleCirclesExtended from 'mdi-material-ui/GoogleCirclesExtended'
import SettingsApplicationsIcon from '@mui/icons-material/SettingsApplications';
// ** Type import
import { VerticalNavItemsType } from '../../core/layouts/types'
@ -29,7 +24,6 @@ const navigation = (): VerticalNavItemsType => {
}, []);
if(isStripeOnboarded){
return [
{
sectionTitle: 'General'
@ -42,11 +36,16 @@ const navigation = (): VerticalNavItemsType => {
{
title: 'Account Settings',
icon: Settings,
path: '/artist/settings'
path: '/dashboard/settings'
},
{
sectionTitle: 'Artist'
},
{
title: 'Shop Settings',
icon: SettingsApplicationsIcon,
path: '/dashboard/artist/artistsettings'
},
{
title: 'Payout Portal',
icon: BankTransfer,
@ -74,7 +73,12 @@ const navigation = (): VerticalNavItemsType => {
title: 'Dashboard',
icon: HomeOutline,
path: '/dashboard'
}
},
{
title: 'Account Settings',
icon: Settings,
path: '/dashboard/settings'
},
]
}
}

View File

@ -1,5 +1,5 @@
import { withPageAuthRequired } from "@auth0/nextjs-auth0";
import Layout from "../../components/OLd/layout";
import Layout from "../../components/Old/layout";
import { User } from "../../interfaces";
type ProfileProps = {

34
pages/api/me.tsx Normal file
View File

@ -0,0 +1,34 @@
import { useRouter } from 'next/router'
import { withApiAuthRequired } from "@auth0/nextjs-auth0";
import { getAccessToken } from '@auth0/nextjs-auth0';
export default withApiAuthRequired(async function me(req, res) {
if(req.method !== 'GET') {
console.log(req.body)
const { accessToken } = await getAccessToken(req, res);
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/User', {
headers: {
"Authorization": `Bearer ${accessToken}`,
"Content-Type": "application/json"
},
method: "PUT",
body: req.body
});
let result = await response.json();
res.status(200).json(result);
}
else{
const { accessToken } = await getAccessToken(req, res);
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/User', {
headers: {
"Authorization": `Bearer ${accessToken}`,
"Content-Type": "application/json"
}
});
let result = await response.json();
res.status(200).json(result);
}
});

View File

@ -1,108 +0,0 @@
import Layout from "../../components/OLd/layout";
import { useUser } from "@auth0/nextjs-auth0/client";
import { Box, Grid, Card, CardContent, Typography, List, Button, CircularProgress, Tooltip } from "@mui/material";
import { useState, useEffect } from "react";
import { useRouter } from 'next/router'
import ArtistPortfolio from "../../components/artistPortfolio";
const SellerProfile = () => {
const { user, isLoading } = useUser();
const router = useRouter()
const { id } = router.query
const [sellerData, setSellerData] = useState([]);
const [loading, setLoading] = useState(true); // State for loading indicator
useEffect(() => {
const getData = async () => {
if(id){
const response = await fetch('/api/discovery/artist/'+id);
const data = await response.json();
setSellerData(data);
setLoading(false); // Once data is fetched, set loading to false
}
}
getData();
}, [id]);
const [value, setValue] = useState(0);
return (
<Layout user={user} loading={isLoading}>
{loading ? ( // Render loading indicator if loading is true
<Box sx={{textAlign:"center", paddingTop:20}}>
<Typography variant="h4" sx={{textAlign:"center"}}>
Loading
</Typography>
<Box sx={{ paddingTop: 5 }} />
<CircularProgress />
</Box>
) : (
<Grid container spacing={2} sx={{padding:4}}>
<Grid container sx={{textAlign:"center"}}>
<Grid item xs={12} sm={2} sx={{textAlign:"center"}}>
<Button color="primary" variant="contained" href="../">
Back
</Button>
</Grid>
<Grid item xs={12} sm={8} sx={{textAlign:"center"}}>
<Typography variant="h4">
{sellerData["name"]}
</Typography>
</Grid>
<Grid item xs={12} sm={2} sx={{textAlign:"center"}}>
</Grid>
</Grid>
<Grid item xs={12} sm={6}>
<Card sx={{height:250, overflowY: 'scroll'}}>
<CardContent>
<Typography variant="h5" sx={{textAlign:"center"}}>
Biography
</Typography>
<Typography sx={{paddingTop:2, textAlign:"center"}}>
{sellerData["biography"]}
</Typography>
</CardContent>
</Card>
</Grid>
<Grid item xs={12} md={6}>
<Card sx={{height:250, overflowY: 'scroll'}}>
<CardContent sx={{textAlign:"center"}}>
<Grid item xs={12} md={12}>
<Typography variant="h5">
Social Media
</Typography>
<List
sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}
aria-label="contacts"
>
</List>
</Grid>
<Grid item xs={12} md={12}>
</Grid>
</CardContent>
</Card>
</Grid>
<Grid item xs={12} sm={12} sx={{textAlign:"center"}} >
{user ? (
<Button size="large" color="secondary" variant="contained" href={"/artist/"+id+"/request"}>
Request Order
</Button>
) : (
<Tooltip title="Log in order to place a request.">
<span>
<Button size="large" color="secondary" variant="contained" disabled>
Submit Request
</Button>
</span>
</Tooltip>
)}
</Grid>
<Grid item xs={12} sm={12}>
<ArtistPortfolio artistId={id} />
</Grid>
</Grid>
)}
</Layout>
);
};
export default SellerProfile;

View File

@ -1,118 +0,0 @@
import Layout from "../../../components/OLd/layout";
import { useUser } from "@auth0/nextjs-auth0/client";
import { Box, Grid, Typography, Button, CircularProgress, TextField} from "@mui/material";
import { useState, useEffect } from "react";
import { useRouter } from 'next/router'
import CurrencyTextField from '@lupus-ai/mui-currency-textfield'
interface TabPanelProps {
children?: React.ReactNode;
index: number;
value: number;
}
const SellerProfile = () => {
const { user, isLoading } = useUser();
const router = useRouter()
const { id } = router.query
const [sellerData, setSellerData] = useState([]);
const [loading, setLoading] = useState(true); // State for loading indicator
useEffect(() => {
const getData = async () => {
if(id){
const response = await fetch('/api/discovery/artist/'+id);
const data = await response.json();
setSellerData(data);
setLoading(false); // Once data is fetched, set loading to false
}
}
getData();
}, [id]);
const handleChange = (event: React.SyntheticEvent, newValue: number) => {
setValue(newValue);
};
const [value, setValue] = useState(0);
return (
<Layout user={user} loading={isLoading}>
{loading ? ( // Render loading indicator if loading is true
<Box sx={{textAlign:"center", paddingTop:20}}>
<Typography variant="h4" sx={{textAlign:"center"}}>
Loading
</Typography>
<Box sx={{ paddingTop: 5 }} />
<CircularProgress />
</Box>
) : (
<Grid container spacing={2} sx={{padding:4}}>
<Grid container sx={{textAlign:"center"}}>
<Grid item xs={12} sm={2} sx={{textAlign:"center"}}>
<Button color="primary" variant="contained" href={"../"+id}>
Back
</Button>
</Grid>
<Grid item xs={12} sm={8} sx={{textAlign:"center"}}>
<Typography variant="h4">
New Request
</Typography>
</Grid>
<Grid item xs={12} sm={2} sx={{textAlign:"center"}}>
</Grid>
</Grid>
<Grid container item xs={12} sm={12} sx={{textAlign:"center"}} >
{user ? (
<>
<Grid item xs={12} sm={12} sx={{textAlign:"center"}} >
<TextField fullWidth disabled id="fo" label="Artist" variant="outlined" value={sellerData["name"]}/>
<Box sx={{padding:2}} />
<TextField id="outlined-multiline-static" label="Request Details" fullWidth multiline rows={4} defaultValue="" placeholder="Put the details of your request. Links to reference images. Descriptions of what you want. Things like that."/>
<Box sx={{padding:2}} />
</Grid>
<Grid item xs={12} sm={12} sx={{textAlign:"center"}} >
<Button>
<input type="file" multiple />
</Button>
</Grid>
<Box sx={{padding:2}} />
<Grid item xs={12} sm={12} sx={{textAlign:"center"}} >
<CurrencyTextField
label="Offer Amount"
variant="standard"
value={value}
currencySymbol="USD "
//minimumValue="0"
outputFormat="string"
decimalCharacter="."
digitGroupSeparator=","
onChange={(event, value)=> setValue(value)}/>
</Grid>
<Box sx={{padding:2}} />
<Grid item xs={12} sm={12} sx={{textAlign:"center"}} >
<Button color="secondary" variant="contained" >
Submit Request
</Button>
</Grid>
</>
) : (
<>
<Typography>
Please login to place a request.
</Typography>
<Button color="primary" variant="contained" href="/api/auth/login">
Login
</Button>
</>
)}
</Grid>
</Grid>
)}
</Layout>
);
};
export default SellerProfile;

View File

@ -0,0 +1,82 @@
import { useUser,withPageAuthRequired } from "@auth0/nextjs-auth0/client";
import { Grid, Typography } from "@mui/material";
import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import EditableArtistPortfolio from "../../../components/Old/editableArtistPortfolio";
import { useEffect, useState } from "react";
import TextField from '@mui/material/TextField';
import Button from '@mui/material/Button';
import Switch from '@mui/material/Switch';
import Divider from '@mui/material/Divider';
const ArtistSettings = () => {
const {user, isLoading} = useUser();
const [profileData, setSellerProfileData] = useState(null);
const getData = async () => {
const profileResponse = await fetch('/api/artist/profile');
const sellerProfile = await profileResponse.json();
setSellerProfileData(sellerProfile);
}
useEffect(() => {
getData()
}, []);
return (
<Grid container spacing={2}>
<Grid item xs={12} md={6}>
<Card>
<CardContent>
<Grid container spacing={2}>
<Grid item xs={12} md={8}>
<Typography variant="h5" gutterBottom>General Settings</Typography>
</Grid>
<Grid item xs={12} md={4} >
<Button variant="contained" color="success" fullWidth>Save Changes</Button>
</Grid>
<Grid item xs={12} md={12} >
<Grid container spacing={2} sx={{paddingTop:"2%"}}>
<Grid item xs={12} md={12} sx={{paddingTop:"2%"}}>
<TextField id="outlined-basic" label="Shop Name" size="small" variant="outlined" fullWidth />
</Grid>
<Grid item xs={12} md={12} sx={{paddingTop:"2%"}}>
<TextField id="outlined-basic" multiline rows={7} size="small" label="Shop Description" variant="outlined" fullWidth />
</Grid>
</Grid>
</Grid>
<Grid item xs={12} md={12} >
<Grid container spacing={2} sx={{paddingTop:"2%"}}>
<Grid item xs={12} md={6} sx={{paddingTop:"2%"}}>
<TextField id="outlined-basic" label="Social Media 1" type="url" size="small" variant="outlined" fullWidth />
</Grid>
<Grid item xs={12} md={6} sx={{paddingTop:"2%"}}>
<TextField id="outlined-basic" label="Social Media 2" type="url" size="small" variant="outlined" fullWidth />
</Grid>
<Grid item xs={12} md={6} sx={{paddingTop:"2%"}}>
<TextField id="outlined-basic" label="Social Media 3" type="url" size="small" variant="outlined" fullWidth />
</Grid>
<Grid item xs={12} md={6} sx={{paddingTop:"2%"}}>
<TextField id="outlined-basic" label="Social Media 4" type="url" size="small" variant="outlined" fullWidth />
</Grid>
<Grid item xs={12} md={12} sx={{paddingTop:"2%"}}>
<TextField id="outlined-basic" multiline rows={5} size="small" label="Your request guidelines" variant="outlined" fullWidth />
</Grid>
</Grid>
</Grid>
</Grid>
</CardContent>
</Card>
</Grid>
<Grid item xs={12} md={6}>
<Card id="portfolio">
<CardContent>
{(profileData != null) ? (
<EditableArtistPortfolio artistId={profileData["id"]}/>):null}
</CardContent>
</Card>
</Grid>
</Grid>
);
};
// Protected route, checking user authentication client-side.(CSR)
export default withPageAuthRequired(ArtistSettings);

View File

@ -14,6 +14,8 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import AccordionDetails from '@mui/material/AccordionDetails';
import Slider from '@mui/material/Slider';
import ArtistPortfolio from '../../../components/Old/artistPortfolio';
import CurrencyTextField from '@lupus-ai/mui-currency-textfield';
import Box from '@mui/material/Box';
const Profile = () => {
@ -37,8 +39,8 @@ const Profile = () => {
const [bioColor, setBioColor] = useState('rgb(186, 186, 186)');
const [bioBgColor, setBioBgColor] = useState('rgb(103, 97, 97)');
const [bioHeaderColor, setBioHeaderColor] = useState('rgb(255, 255, 255)');
const [bioBgColor, setBioBgColor] = useState('rgb(78, 73, 73)');
const [bioHeaderColor, setBioHeaderColor] = useState('rgb(194, 187, 187)');
const [bioHeaderIsImage, setBioHeaderImage] = useState(false);
const [bioHeaderImageUrl, setBioHeaderImageUrl] = useState('');
const [bioHeaderText, setBioHeaderText] = useState('Biography');
@ -61,11 +63,47 @@ const Profile = () => {
'h1', // Size 6
][bioSize - 1] || 'h6';
const [portfolioHeaderColor, setPortfolioHeaderColor] = useState('rgb(194, 187, 187)');
const [portfolioHeaderIsImage, setPortfolioHeaderImage] = useState(false);
const [portfolioHeaderImageUrl, setPortfolioHeaderImageUrl] = useState('');
const [portfolioHeaderText, setPortfolioHeaderText] = useState('Portfolio');
const [portfolioHeaderSize, setPortfolioHeaderSize] = useState(3);
const [portfolioBgColor, setPortfolioBgColor] = useState('rgb(78, 73, 73)');
const [portfolioColumns, setPotrfolioColumns] = useState(2);
const [portfolioWoven, setPortfolioWoven] = useState(true);
const [portfolioShouldScroll, setPortfolioShouldScroll] = useState(true);
const [portfolioSize, setPortfolioSize] = useState(25);
const portfolioVariant = [
'h6', // Size 1
'h5', // Size 2
'h4', // Size 3
'h3', // Size 4
'h2', // Size 5
'h1', // Size 6
][portfolioHeaderSize - 1] || 'h6';
const [requestHeaderColor, setRequestHeaderColor] = useState('rgb(194, 187, 187)');
const [requestHeaderIsImage, setRequestHeaderImage] = useState(false);
const [requestHeaderImageUrl, setRequestHeaderImageUrl] = useState('');
const [requestHeaderText, setRequestHeaderText] = useState('Requests');
const [requestHeaderSize, setRequestHeaderSize] = useState(3);
const [requestBgColor, setRequestBgColor] = useState('rgb(78, 73, 73)');
const [requestTermsTextColor, setRequestTermsTextColor] = useState('rgb(194, 187, 187)');
const [requestButtonBGColor, setRequestButtonBGColor] = useState('rgb(101, 97, 97)');
const [requestButtonTextColor, setRequestButtonTextColor] = useState('rgb(194, 187, 187)');
const [requestHoverButtonBGColor, setRequestHoverButtonBGColor] = useState('rgb(98, 98, 98)');
const [requestHoverButtonTextColor, setRequestHoverButtonTextColor] = useState('rgb(194, 187, 187)');
const requestVariant = [
'h6', // Size 1
'h5', // Size 2
'h4', // Size 3
'h3', // Size 4
'h2', // Size 5
'h1', // Size 6
][requestHeaderSize - 1] || 'h6';
const getData = async () => {
const profileResponse = await fetch('/api/artist/profile');
@ -152,6 +190,66 @@ const Profile = () => {
setPortfolioSize(newValue)
}
const handlePortfolioHeaderTextChange = (e) => {
setPortfolioHeaderText(e.target.value)
}
const handlePortfolioHeaderImageUrl = (e) => {
setPortfolioHeaderImageUrl(e.target.value)
}
const handlePortfolioHeaderImageToggle = (e) => {
setPortfolioHeaderImage(e.target.checked)
};
const handlePortfolioHeaderSize = (e, newValue) => {
setPortfolioHeaderSize(newValue)
}
const handlePortfolioHeaderColorChange = (newValue) => {
setPortfolioHeaderColor(newValue)
}
const handleRequestBgColor = (newValue) => {
setRequestBgColor(newValue)
}
const handleRequestHeaderTextChange = (e) => {
setRequestHeaderText(e.target.value)
}
const handleRequestHeaderImageUrl = (e) => {
setRequestHeaderImageUrl(e.target.value)
}
const handleRequestHeaderImageToggle = (e) => {
setRequestHeaderImage(e.target.checked)
};
const handleRequestHeaderSize = (e, newValue) => {
setRequestHeaderSize(newValue)
}
const handleRequestHeaderColorChange = (newValue) => {
setRequestHeaderColor(newValue)
}
const handleRequestTermsTextColorChange = (newValue) => {
setRequestTermsTextColor(newValue)
}
const handleRequestButtonBGColorChange = (newValue) => {
setRequestButtonBGColor(newValue)
}
const handleRequestButtonTextColorChange = (newValue) => {
setRequestButtonTextColor(newValue)
}
const handleRequestHoverButtonBGColorChange = (newValue) => {
setRequestHoverButtonBGColor(newValue)
}
const handleRequestHoverButtonTextColorChange = (newValue) => {
setRequestHoverButtonTextColor(newValue)
}
return (
<Grid container spacing={2}>
<Grid item xs={12} md={4}>
@ -164,7 +262,7 @@ const Profile = () => {
</Typography>
</Grid>
<Grid item xs={12} md={3}>
<Button variant="contained" size="large">
<Button color="success" variant="contained" size="large">
Save
</Button>
</Grid>
@ -232,6 +330,7 @@ const Profile = () => {
</AccordionSummary>
<AccordionDetails>
<Grid container spacing={2}>
<Grid item xs={12} md={12}>
<TextField disabled={bioHeaderIsImage} variant="outlined" fullWidth label="Header Text" onChange={handleBioHeaderTextChange} value={bioHeaderText} size="small"></TextField>
</Grid>
@ -280,6 +379,26 @@ const Profile = () => {
</AccordionSummary>
<AccordionDetails>
<Grid container spacing={2}>
<Grid item xs={12} md={12}>
<TextField disabled={portfolioHeaderIsImage} variant="outlined" fullWidth label="Header Text" onChange={handlePortfolioHeaderTextChange} value={portfolioHeaderText} size="small"></TextField>
</Grid>
<Grid item xs={12} md={10}>
<TextField variant="outlined" fullWidth label="Header Image Url" size="small" value={portfolioHeaderImageUrl} onChange={handlePortfolioHeaderImageUrl}></TextField>
</Grid>
<Grid item xs={12} md={2}>
<Switch checked={portfolioHeaderIsImage} onChange={handlePortfolioHeaderImageToggle} />
</Grid>
<Grid item xs={12} md={12}>
<MuiColorInput disabled={portfolioHeaderIsImage} label="Header Text Color" fullWidth value={portfolioHeaderColor} onChange={handlePortfolioHeaderColorChange} />
</Grid>
<Grid item xs={12} md={5}>
<Typography variant="body1" >
Header Size
</Typography>
</Grid>
<Grid item xs={12} md={7}>
<Slider disabled={portfolioHeaderIsImage} value={portfolioHeaderSize} onChange={handlePortfolioHeaderSize} aria-label="Size" defaultValue={6} step={1} marks min={1} max={6} />
</Grid>
<Grid item xs={12} md={12}>
<MuiColorInput label="Background Color" fullWidth value={portfolioBgColor} onChange={handlePortfolioBgColor} />
</Grid>
@ -320,6 +439,59 @@ const Profile = () => {
</Accordion>
</Grid>
<Grid item xs={12} md={12}>
<Accordion defaultExpanded>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1-content"
>
<Typography>Requests</Typography>
</AccordionSummary>
<AccordionDetails>
<Grid container spacing={2}>
<Grid item xs={12} md={12}>
<TextField disabled={requestHeaderIsImage} variant="outlined" fullWidth label="Header Text" onChange={handleRequestHeaderTextChange} value={requestHeaderText} size="small"></TextField>
</Grid>
<Grid item xs={12} md={10}>
<TextField variant="outlined" fullWidth label="Header Image Url" size="small" value={requestHeaderImageUrl} onChange={handleRequestHeaderImageUrl}></TextField>
</Grid>
<Grid item xs={12} md={2}>
<Switch checked={requestHeaderIsImage} onChange={handleRequestHeaderImageToggle} />
</Grid>
<Grid item xs={12} md={12}>
<MuiColorInput disabled={requestHeaderIsImage} label="Header Text Color" fullWidth value={requestHeaderColor} onChange={handleRequestHeaderColorChange} />
</Grid>
<Grid item xs={12} md={5}>
<Typography variant="body1" >
Header Size
</Typography>
</Grid>
<Grid item xs={12} md={7}>
<Slider disabled={requestHeaderIsImage} value={requestHeaderSize} onChange={handleRequestHeaderSize} aria-label="Size" defaultValue={6} step={1} marks min={1} max={6} />
</Grid>
<Grid item xs={12} md={12}>
<MuiColorInput label="Background Color" fullWidth value={requestBgColor} onChange={handleRequestBgColor} />
</Grid>
<Grid item xs={12} md={12}>
<MuiColorInput label="Terms Text Color" fullWidth value={requestTermsTextColor} onChange={handleRequestTermsTextColorChange} />
</Grid>
<Grid item xs={12} md={12}>
<MuiColorInput label="Button BG Color" fullWidth value={requestButtonBGColor} onChange={handleRequestButtonBGColorChange} />
</Grid>
<Grid item xs={12} md={12}>
<MuiColorInput label="Button Text Color" fullWidth value={requestButtonTextColor} onChange={handleRequestButtonTextColorChange} />
</Grid>
<Grid item xs={12} md={12}>
<MuiColorInput label="Button Hover BG Color" fullWidth value={requestHoverButtonBGColor} onChange={handleRequestHoverButtonBGColorChange} />
</Grid>
<Grid item xs={12} md={12}>
<MuiColorInput label="Button Hover Text Color" fullWidth value={requestHoverButtonTextColor} onChange={handleRequestHoverButtonTextColorChange} />
</Grid>
</Grid>
</AccordionDetails>
</Accordion>
</Grid>
</Grid>
</CardContent>
</Card>
@ -354,8 +526,18 @@ const Profile = () => {
</CardContent>
</Card>
</Grid>
<Grid item xs={12} md={12} sx={{textAlign:"center", marginTop:"2%"}}>
<Grid item xs={12} md={12} sx={{ marginTop:"2%"}}>
<Card sx={{backgroundColor:portfolioBgColor}}>
<Box sx={{textAlign:"center", paddingTop:"2%"}}>
{(portfolioHeaderIsImage) ? (
<img src={portfolioHeaderImageUrl} alt="Header Image" />
) : (
<Typography sx={{paddingBottom:"2%"}} variant={portfolioVariant} color={portfolioHeaderColor}>
{portfolioHeaderText}
</Typography>
)}
</Box>
{(portfolioShouldScroll)?(
<CardContent sx={{height:`${portfolioSize}rem`, overflowY:"scroll",}}>
{(profileData ? (
@ -371,6 +553,41 @@ const Profile = () => {
)}
</Card>
</Grid>
<Grid xs={12} md={12} sx={{ marginTop:"2%"}}>
<Card sx={{backgroundColor:requestBgColor}}>
<CardContent>
<Grid container>
<Grid item xs={12} md={12} sx={{textAlign:"center"}}>
{(requestHeaderIsImage) ? (
<img src={requestHeaderImageUrl} alt="Header Image" />
) : (
<Typography sx={{paddingBottom:"2%"}} variant={requestVariant} color={requestHeaderColor}>
{requestHeaderText}
</Typography>
)}
</Grid>
<Grid item xs={12} md={12} sx={{textAlign:"center"}}>
<Typography variant="body1" color={requestTermsTextColor}>
TERMS
</Typography>
</Grid>
<Grid item xs={12} md={12} sx={{textAlign:"center"}}>
<Typography color="white" variant="body2">By clicking the button below, you agree to the
terms and conditions.</Typography>
</Grid>
<Grid item xs={12} md={12} sx={{textAlign:"center"}}>
</Grid>
<Grid item xs={12} md={12} sx={{textAlign:"center",paddingTop:"2%"}}>
<Button size="large" variant="contained" sx={{backgroundColor:requestButtonBGColor, color:requestButtonTextColor,
':hover': {
bgcolor: requestHoverButtonBGColor, // theme.palette.primary.main
color: requestHoverButtonTextColor,
},}}>Agree And Start Request</Button>
</Grid>
</Grid>
</CardContent>
</Card>
</Grid>
</Grid>
</CardContent>
</Card>

View File

@ -13,7 +13,7 @@ import CardStatisticsVerticalComponent from '../../core/components/card-statisti
// ** Styled Component Import
import ApexChartWrapper from '../../core/styles/libs/react-apexcharts'
import { Card, Typography } from '@mui/material'
import { Card, TextField, Typography } from '@mui/material'
import { withApiAuthRequired } from "@auth0/nextjs-auth0";
import { withPageAuthRequired } from '@auth0/nextjs-auth0/client'
import Button from '@mui/material/Button'
@ -21,8 +21,12 @@ import { CardContent } from '@mui/material'
import Onboarding from '../../components/Onboarding'
import { useState } from 'react'
import { useEffect } from 'react'
import router from 'next/router'
import { isObject } from 'util'
import Orders from '../../components/Orders'
import StatisticsCard from '../../views/dashboard/StatisticsCard'
import SellerStats from '../../components/SellerStats'
import { Clipboard } from 'mdi-material-ui'
@ -70,12 +74,17 @@ const Dashboard = () => {
<Card>
<CardContent>
<Grid container>
<Grid item xs={12} md={12} sx={{textAlign:"center"}}>
<Grid item xs={12} md={3} sx={{textAlign:"center"}}>
<Typography variant="h5" gutterBottom>
My Orders
</Typography>
</Grid>
<Grid item xs={12} md={12}>
<Grid item xs={12} md={4} sx={{textAlign:"center"}}>
</Grid>
<Grid item xs={12} md={5} sx={{textAlign:"center"}}>
<Button color="info" onClick={()=>{router.push("/dashboard/orders")}} fullWidth variant="contained">View All Orders</Button>
</Grid>
<Grid item xs={12} md={12} sx={{paddingTop:"2%"}}>
<Orders />
</Grid>
</Grid>
@ -90,15 +99,33 @@ const Dashboard = () => {
</Grid>
):(
(onboarding) ? (
<Grid item xs={12} md={6}>
<Grid item xs={12} md={6}>
<Card sx={{textAlign:"center", width:"100%"}}>
<CardContent>
<Grid container>
<Grid item xs={12} md={6}>
<Button color="secondary" sx={{width:"90%"}} variant="contained">Manage Portfolio</Button>
<Grid spacing={3} container>
<Grid item xs={12} md={12} >
<SellerStats />
</Grid>
<Grid item xs={12} md={8}>
<TextField size="small" label="Your Public URL" variant="outlined" disabled fullWidth defaultValue={"http://localhost:3000/shops/neroshi"}>"http://localhost:3000/shops/neroshi"</TextField>
</Grid>
<Grid item xs={12} md={2}>
<Button color="info" startIcon={<Clipboard/>} onClick={()=>{router.push("/dashboard/artist/artistsettings#portfolio")}} fullWidth variant="outlined">Copy</Button>
</Grid>
<Grid item xs={12} md={2}>
<Button color="secondary" onClick={()=>{router.push("/dashboard/artist/artistsettings#portfolio")}} fullWidth variant="outlined">Preview</Button>
</Grid>
<Grid item xs={12} md={6}>
<Button color="primary" href="/dashboard/artist/pagesettings" fullWidth sx={{width:"90%"}} variant="contained">Design Store Page</Button>
<Button color="secondary" onClick={()=>{router.push("/dashboard/artist/artistsettings#portfolio")}} fullWidth variant="contained">Manage Portfolio</Button>
</Grid>
<Grid item xs={12} md={6}>
<Button color="secondary" onClick={()=>{router.push("/dashboard/artist/pagesettings")}} fullWidth variant="contained">Design Store Page</Button>
</Grid>
<Grid item xs={12} md={6}>
<Button color="secondary" onClick={()=>{router.push("/dashboard/artist/pagesettings")}} fullWidth variant="contained">Payment Portal</Button>
</Grid>
<Grid item xs={12} md={6}>
<Button color="secondary" onClick={()=>{router.push("/dashboard/artist/pagesettings")}} fullWidth variant="contained">Configure Your Shop</Button>
</Grid>
</Grid>
</CardContent>

View File

@ -0,0 +1,76 @@
import { useUser, withPageAuthRequired } from "@auth0/nextjs-auth0/client";
import { Grid, Typography } from "@mui/material";
import { useEffect, useState } from "react";
import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import TextField from '@mui/material/TextField';
import Button from '@mui/material/Button';
const ArtistSettings = () => {
const { user, isLoading } = useUser();
const [appUser, setAppUser] = useState(null);
const [displayName, setDisplayName] = useState("");
const [biography, setBiography] = useState("");
const [saved, setSaved] = useState(false);
const handleDisplayNameChange = (event) => {
setDisplayName(event.target.value);
}
const handleBiographyChange = (event) => {
setBiography(event.target.value);
}
const saveChanges = async () => {
var userResponse = await fetch('/api/me',{
method: 'PUT',
body: JSON.stringify({displayName: displayName, biography: biography})
});
var user = await userResponse.json();
setSaved(true);
}
useEffect(() => {
getData()
}, []);
const getData = async () => {
var userResponse = await fetch('/api/me');
var user = await userResponse.json();
setDisplayName(user["displayName"])
setBiography(user["biography"])
setAppUser(user);
}
return (
<Grid container spacing={2}>
<Grid item xs={12} md={6}>
<Card>
<CardContent>
<Grid container item md={12}>
<Grid item xs={12} md={8}>
<Typography variant="h5" gutterBottom>General Settings</Typography>
</Grid>
<Grid item xs={12} md={4} >
{(saved) ? (
<Button variant="contained" color="success" fullWidth onClick={saveChanges}>Saved</Button>
):(
<Button variant="contained" color="success" fullWidth onClick={saveChanges}>Save Changes</Button>
)}
</Grid>
<Grid item xs={12} md={12} sx={{ paddingTop: "2%" }}>
<TextField id="outlined-basic" label="Display Name" onChange={handleDisplayNameChange} variant="outlined" fullWidth value={displayName} />
</Grid>
<Grid item xs={12} md={12} sx={{ paddingTop: "2%" }}>
<TextField id="outlined-basic" multiline rows={5} label="Biography" onChange={handleBiographyChange} variant="outlined" value={biography} fullWidth />
</Grid>
</Grid>
</CardContent>
</Card>
</Grid>
</Grid>
);
};
// Protected route, checking user authentication client-side.(CSR)
export default withPageAuthRequired(ArtistSettings);

View File

@ -1,32 +0,0 @@
import { withPageAuthRequired } from "@auth0/nextjs-auth0/client";
import { User } from "../interfaces";
type ProfileCardProps = {
user: User;
};
const ProfileCard = ({ user }: ProfileCardProps) => {
return (
<>
<h1>Profile</h1>
<div>
<h3>Profile (client rendered)</h3>
<img src={user.picture} alt="user picture" />
<p>nickname: {user.nickname}</p>
<p>name: {user.name}</p>
</div>
</>
);
};
const Profile = ({ user, isLoading }) => {
return (
<>
{isLoading ? <>Loading</> : <ProfileCard user={user} />}
</>
);
};
// Protected route, checking user authentication client-side.(CSR)
export default withPageAuthRequired(Profile);

View File

@ -1,38 +0,0 @@
import { useUser } from "@auth0/nextjs-auth0/client";
import Layout from "../components/OLd/layout";
import { Grid, Button, Typography, TextField, Box } from "@mui/material";
const Settings = () => {
const { user, isLoading } = useUser();
return (
<Layout user={user} loading={isLoading}>
<Grid container spacing={2} sx={{padding:4}}>
<Grid container sx={{textAlign:"center"}}>
<Grid item xs={12} sm={2} sx={{textAlign:"center"}}>
<Button color="primary" variant="contained" href="../">
Back
</Button>
</Grid>
<Grid item xs={12} sm={8} sx={{textAlign:"center"}}>
<Typography variant="h4">
Settings
</Typography>
</Grid>
<Grid item xs={12} sm={2} sx={{textAlign:"center"}}>
<Button color="secondary" variant="contained" href="../">
Save
</Button>
</Grid>
</Grid>
<Grid item xs={12} sm={12}>
<TextField variant="filled" fullWidth label="Display Name" value={user?.email} />
<Box sx={{padding:2}} />
<TextField variant="outlined" fullWidth multiline rows={4} label="Biography" value={user?.email} />
</Grid>
</Grid>
</Layout>
);
};
export default Settings;