mirror of
https://github.com/D4M13N-D3V/comissions-app-ui.git
synced 2025-03-14 00:05:07 +00:00
ui
This commit is contained in:
parent
52c111ab36
commit
ed48b67e3c
@ -40,13 +40,13 @@ const Artist = ({user, artistId}) => {
|
||||
<Grid item xs={6} md={8}>
|
||||
<Item>
|
||||
<Typography variant="h5" component="h2">
|
||||
{sellerData.name}
|
||||
{sellerData["name"]}
|
||||
</Typography>
|
||||
<Typography color="primary">
|
||||
{sellerData.averageRating ? `${sellerData.averageRating} Stars (${sellerData.reviewCount} Reviews)` : "No Reviews"}
|
||||
{sellerData["averageRating"] ? `${sellerData["averageRating"]} Stars (${sellerData["reviewCount"]} Reviews)` : "No Reviews"}
|
||||
</Typography>
|
||||
<Typography variant="body2" component="p">
|
||||
{sellerData.biography}
|
||||
{sellerData["biography"]}
|
||||
</Typography>
|
||||
</Item>
|
||||
|
||||
|
@ -13,14 +13,14 @@ const ArtistPortfolio = ({artistId}) => {
|
||||
setPortfolioData(data);
|
||||
setLoading(false);
|
||||
}
|
||||
console.log(portfolioData)
|
||||
//console.log(portfolioData)
|
||||
getData();
|
||||
}, []);
|
||||
return (
|
||||
(loading) ? (
|
||||
<Box sx={{textAlign:"center", paddingTop:20}}>
|
||||
<Typography variant="h4" sx={{textAlign:"center"}}>
|
||||
Loading...
|
||||
Loading
|
||||
</Typography>
|
||||
<CircularProgress sx={{paddingTop:5}} />
|
||||
</Box>
|
||||
|
80
components/editableArtistPortfolio.tsx
Normal file
80
components/editableArtistPortfolio.tsx
Normal file
@ -0,0 +1,80 @@
|
||||
import * as React from 'react';
|
||||
import { ImageList, Box, Button, CircularProgress } 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 [loading, setLoading] = useState(true); // State for loading indicator
|
||||
useEffect(() => {
|
||||
getData();
|
||||
}, []);
|
||||
|
||||
const getData = async () => {
|
||||
const response = await fetch('/api/discovery/artist/' + artistId + '/portfolio');
|
||||
const data = await response.json();
|
||||
setPortfolioData(data);
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
function handlePortfolioUploadImageChange(event) {
|
||||
const file = event.target.files[0];
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
fetch('/api/artist/portfolio', {
|
||||
method: 'POST',
|
||||
body: formData // Don't set Content-Type, FormData will handle it
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
getData();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error uploading file:', error);
|
||||
// Handle error appropriately
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
(loading) ? (
|
||||
<Box sx={{ textAlign: "center", paddingTop: 20 }}>
|
||||
<CircularProgress sx={{ paddingTop: 5 }} />
|
||||
</Box>
|
||||
) :
|
||||
(
|
||||
<Grid container spacing={2} sx={{ padding: 4 }}>
|
||||
<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"
|
||||
startIcon={<FileOpenIcon />}
|
||||
>
|
||||
Add Image
|
||||
</Button>
|
||||
</label>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={12} sx={{ textAlign: "center" }}>
|
||||
<ImageList cols={2} rowHeight={200} sx={{ maxHeight: 400 }}>
|
||||
{portfolioData.map((item) => (
|
||||
<EditableArtistPortfolioImage artistId={artistId} itemId={item.id} />
|
||||
))}
|
||||
</ImageList>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
)
|
||||
}
|
||||
export default EditableArtistPortfolio
|
28
components/editableArtistPortfolioImage.tsx
Normal file
28
components/editableArtistPortfolioImage.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import * as React from 'react';
|
||||
import ImageList from '@mui/material/ImageList';
|
||||
import ImageListItem from '@mui/material/ImageListItem';
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { CircularProgress } from '@mui/material';
|
||||
|
||||
import { IconButton } from '@mui/material';
|
||||
|
||||
const EditableArtistPortfolioImage = ({artistId,itemId}) => {
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const handleImageLoaded = () => {
|
||||
setLoaded(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<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}`}
|
||||
alt={itemId}
|
||||
loading="lazy"
|
||||
style={{ filter: loaded ? 'blur(0)' : 'blur(10px)', backgroundColor:'grey' }}
|
||||
onLoad={handleImageLoaded}
|
||||
/>
|
||||
</ImageListItem>)
|
||||
}
|
||||
export default EditableArtistPortfolioImage
|
49
package-lock.json
generated
49
package-lock.json
generated
@ -16,6 +16,7 @@
|
||||
"@mui/x-date-pickers": "^6.19.4",
|
||||
"@novu/notification-center": "^0.22.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"formidable": "^3.5.1",
|
||||
"next": "latest",
|
||||
"openapi-typescript-fetch": "^1.1.3",
|
||||
"react": "^18.2.0",
|
||||
@ -1259,6 +1260,11 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/asap": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
@ -1478,6 +1484,15 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/dezalgo": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
|
||||
"integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
|
||||
"dependencies": {
|
||||
"asap": "^2.0.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-helpers": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
|
||||
@ -1563,6 +1578,19 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/formidable": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz",
|
||||
"integrity": "sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==",
|
||||
"dependencies": {
|
||||
"dezalgo": "^1.0.4",
|
||||
"hexoid": "^1.0.0",
|
||||
"once": "^1.4.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://ko-fi.com/tunnckoCore/commissions"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
@ -1595,6 +1623,14 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/hexoid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
|
||||
"integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/hoist-non-react-statics": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
@ -1846,6 +1882,14 @@
|
||||
"node": "^10.13.0 || >=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/openapi-typescript-fetch": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/openapi-typescript-fetch/-/openapi-typescript-fetch-1.1.3.tgz",
|
||||
@ -2326,6 +2370,11 @@
|
||||
"resolved": "https://registry.npmjs.org/webfontloader/-/webfontloader-1.6.28.tgz",
|
||||
"integrity": "sha512-Egb0oFEga6f+nSgasH3E0M405Pzn6y3/9tOVanv/DLfa1YBIgcv90L18YyWnvXkRbIM17v5Kv6IT2N6g1x5tvQ=="
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.11.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
|
||||
|
@ -17,6 +17,7 @@
|
||||
"@mui/x-date-pickers": "^6.19.4",
|
||||
"@novu/notification-center": "^0.22.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"formidable": "^3.5.1",
|
||||
"next": "latest",
|
||||
"openapi-typescript-fetch": "^1.1.3",
|
||||
"react": "^18.2.0",
|
||||
|
49
pages/api/artist/portfolio.tsx
Normal file
49
pages/api/artist/portfolio.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
import { getAccessToken, withApiAuthRequired } from '@auth0/nextjs-auth0';
|
||||
import { IncomingForm } from 'formidable'
|
||||
|
||||
export const config = {
|
||||
api: {
|
||||
bodyParser: false,
|
||||
},
|
||||
};
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
|
||||
const form = new IncomingForm();
|
||||
|
||||
form.parse(req, async (err, fields, files) => {
|
||||
if (err) {
|
||||
console.error('Error parsing form:', err);
|
||||
res.status(500).json({ error: 'Error parsing form' });
|
||||
return;
|
||||
}
|
||||
const file = files["file"]; // Assuming your file input field name is 'file'
|
||||
console.log(file)
|
||||
const formData = new FormData();
|
||||
formData.append('file', file); // Append the file to FormData
|
||||
|
||||
console.log(formData)
|
||||
try {
|
||||
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL + '/api/SellerProfile/Portfolio', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
},
|
||||
body: formData // Don't set Content-Type, FormData will handle it
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.message || 'Failed to upload file');
|
||||
}
|
||||
|
||||
const responseData = await response.json();
|
||||
res.status(200).json(responseData);
|
||||
} catch (error) {
|
||||
console.error('Error uploading file:', error);
|
||||
res.status(500).json({ error: 'Error uploading file' });
|
||||
}
|
||||
});
|
||||
});
|
@ -1,13 +1,13 @@
|
||||
export default async function handler(req, res ): Promise<any> {
|
||||
const { sellerId } = req.query;
|
||||
var url = process.env.NEXT_PUBLIC_API_URL+`/api/Discovery/Sellers/${sellerId}/Portfolio`;
|
||||
console.log(url)
|
||||
//console.log(url)
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch seller portfolio');
|
||||
}
|
||||
var result = await response.json();
|
||||
console.log(result)
|
||||
//console.log(result)
|
||||
res.status(200).json(result);
|
||||
}
|
||||
|
||||
|
@ -30,10 +30,11 @@ const SellerProfile = () => {
|
||||
{loading ? ( // Render loading indicator if loading is true
|
||||
<Box sx={{textAlign:"center", paddingTop:20}}>
|
||||
<Typography variant="h4" sx={{textAlign:"center"}}>
|
||||
Loading...
|
||||
Loading
|
||||
</Typography>
|
||||
<CircularProgress sx={{paddingTop:5}} />
|
||||
</Box>
|
||||
<Box sx={{ paddingTop: 5 }} />
|
||||
<CircularProgress />
|
||||
</Box>
|
||||
) : (
|
||||
<Grid container spacing={2} sx={{padding:4}}>
|
||||
<Grid container sx={{textAlign:"center"}}>
|
||||
@ -44,7 +45,7 @@ const SellerProfile = () => {
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={8} sx={{textAlign:"center"}}>
|
||||
<Typography variant="h4">
|
||||
{sellerData.name}
|
||||
{sellerData["name"]}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={2} sx={{textAlign:"center"}}>
|
||||
@ -57,7 +58,7 @@ const SellerProfile = () => {
|
||||
Biography
|
||||
</Typography>
|
||||
<Typography sx={{paddingTop:2, textAlign:"center"}}>
|
||||
{sellerData.biography}
|
||||
{sellerData["biography"]}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
@ -40,9 +40,10 @@ const SellerProfile = () => {
|
||||
{loading ? ( // Render loading indicator if loading is true
|
||||
<Box sx={{textAlign:"center", paddingTop:20}}>
|
||||
<Typography variant="h4" sx={{textAlign:"center"}}>
|
||||
Loading...
|
||||
Loading
|
||||
</Typography>
|
||||
<CircularProgress sx={{paddingTop:5}} />
|
||||
<Box sx={{ paddingTop: 5 }} />
|
||||
<CircularProgress />
|
||||
</Box>
|
||||
) : (
|
||||
<Grid container spacing={2} sx={{padding:4}}>
|
||||
@ -65,7 +66,7 @@ const SellerProfile = () => {
|
||||
<>
|
||||
|
||||
<Grid item xs={12} sm={12} sx={{textAlign:"center"}} >
|
||||
<TextField fullWidth disabled id="fo" label="Artist" variant="outlined" value={sellerData.name}/>
|
||||
<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}} />
|
||||
|
@ -12,6 +12,7 @@ import CardActions from '@mui/material/CardActions';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import SwipeableViews from '../components/swipableView';
|
||||
import { DataGrid, GridColDef, GridValueGetterParams } from '@mui/x-data-grid';
|
||||
import EditableArtistPortfolio from "../components/editableArtistPortfolio";
|
||||
|
||||
|
||||
|
||||
@ -146,9 +147,10 @@ const SellerDashoard = (ctx) => {
|
||||
{loading ? ( // Render loading indicator if loading is true
|
||||
<Box sx={{ textAlign: "center", paddingTop: 20 }}>
|
||||
<Typography variant="h4" sx={{ textAlign: "center" }}>
|
||||
Loading...
|
||||
Loading
|
||||
</Typography>
|
||||
<CircularProgress sx={{ paddingTop: 5 }} />
|
||||
<Box sx={{ paddingTop: 5 }} />
|
||||
<CircularProgress />
|
||||
</Box>
|
||||
) : (
|
||||
<Layout user={user} loading={isLoading}>
|
||||
@ -240,7 +242,7 @@ const SellerDashoard = (ctx) => {
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel value={tabValue} index={1} dir={theme.direction}>
|
||||
Item Two
|
||||
<EditableArtistPortfolio artistId={sellerData["id"]}></EditableArtistPortfolio>
|
||||
</TabPanel>
|
||||
<TabPanel value={tabValue} index={2} dir={theme.direction}>
|
||||
Item Three
|
||||
@ -262,70 +264,7 @@ const SellerDashoard = (ctx) => {
|
||||
</>
|
||||
|
||||
) : (
|
||||
<>
|
||||
<Grid item container sx={{ textAlign: "center" }}>
|
||||
<Grid item xs={12} sm={10} sx={{ textAlign: "center" }}>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={2} sx={{ textAlign: "center" }}>
|
||||
<Button color="secondary" variant="contained" href="../">
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item container xs={12} sm={12}>
|
||||
<Grid item xs={12} sm={12}>
|
||||
<TextField variant="filled" fullWidth label="Artist Name" />
|
||||
<Box sx={{ padding: 1 }} />
|
||||
<TextField variant="outlined" fullWidth multiline rows={4} label="Biography" />
|
||||
<Box sx={{ padding: 1 }} />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={12} sx={{ textAlign: "center" }}>
|
||||
<Button sx={{ width: "50%" }} color="success" variant="contained">Payout Portal</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item container xs={12} sm={12}>
|
||||
|
||||
<AppBar position="static">
|
||||
<Tabs
|
||||
value={tabValue}
|
||||
onChange={handleChange}
|
||||
indicatorColor="secondary"
|
||||
textColor="inherit"
|
||||
variant="fullWidth"
|
||||
aria-label="full width tabs example"
|
||||
>
|
||||
<Tab label="New Requests" {...a11yProps(0)} />
|
||||
<Tab label="Portfolio" {...a11yProps(1)} />
|
||||
<Tab label="Ongoing Requests" {...a11yProps(2)} />
|
||||
</Tabs>
|
||||
</AppBar>
|
||||
<SwipeableViews
|
||||
index={tabValue}
|
||||
onChangeIndex={handleChangeIndex}
|
||||
>
|
||||
<TabPanel value={tabValue} index={0} dir={theme.direction}>
|
||||
<DataGrid
|
||||
rows={rows}
|
||||
columns={columns}
|
||||
initialState={{
|
||||
pagination: {
|
||||
paginationModel: { page: 0, pageSize: 5 },
|
||||
},
|
||||
}}
|
||||
pageSizeOptions={[5, 10]}
|
||||
sx={{ width: '100%' }}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel value={tabValue} index={1} dir={theme.direction}>
|
||||
Item Two
|
||||
</TabPanel>
|
||||
<TabPanel value={tabValue} index={2} dir={theme.direction}>
|
||||
Item Three
|
||||
</TabPanel>
|
||||
</SwipeableViews>
|
||||
</Grid>
|
||||
</>
|
||||
<></>
|
||||
))}
|
||||
<Grid item container xs={12} sm={12}>
|
||||
</Grid>
|
||||
|
@ -22,9 +22,10 @@ const Home = () => {
|
||||
{loading ? ( // Render loading indicator if loading is true
|
||||
<Box sx={{textAlign:"center", paddingTop:20}}>
|
||||
<Typography variant="h4" sx={{textAlign:"center"}}>
|
||||
Loading...
|
||||
Loading
|
||||
</Typography>
|
||||
<CircularProgress sx={{paddingTop:5}} />
|
||||
<Box sx={{ paddingTop: 5 }} />
|
||||
<CircularProgress />
|
||||
</Box>
|
||||
) : (
|
||||
<>
|
||||
|
@ -24,7 +24,7 @@ const ProfileCard = ({ user }: ProfileCardProps) => {
|
||||
const Profile = ({ user, isLoading }) => {
|
||||
return (
|
||||
<Layout user={user} loading={isLoading}>
|
||||
{isLoading ? <>Loading...</> : <ProfileCard user={user} />}
|
||||
{isLoading ? <>Loading</> : <ProfileCard user={user} />}
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user