From 52c111ab360190c21350cf95109551201310f9a1 Mon Sep 17 00:00:00 2001 From: Damien Ostler Date: Wed, 14 Feb 2024 21:14:25 -0500 Subject: [PATCH] feat: artist dashboard --- components/artist.tsx | 6 +- components/artistPortfolio.tsx | 2 +- components/header.tsx | 4 +- package-lock.json | 72 ++++ package.json | 2 + .../request.tsx => artist/newRequest.tsx} | 0 pages/api/artist/onboarded.tsx | 14 + pages/api/artist/onboardurl.tsx | 14 + pages/api/{seller => artist}/profile.tsx | 1 - pages/api/artist/request.tsx | 20 ++ .../{seller => artist}/[sellerId].tsx | 0 .../[sellerId]/portfolio.tsx | 0 .../discovery/{sellers.tsx => artists.tsx} | 0 pages/{seller => artist}/[id].tsx | 4 +- pages/{seller => artist}/[id]/request.tsx | 2 +- pages/artistDashboard.tsx | 338 ++++++++++++++++++ pages/index.tsx | 2 +- pages/sellerDashboard.tsx | 188 ---------- 18 files changed, 470 insertions(+), 199 deletions(-) rename pages/api/{seller/request.tsx => artist/newRequest.tsx} (100%) create mode 100644 pages/api/artist/onboarded.tsx create mode 100644 pages/api/artist/onboardurl.tsx rename pages/api/{seller => artist}/profile.tsx (95%) create mode 100644 pages/api/artist/request.tsx rename pages/api/discovery/{seller => artist}/[sellerId].tsx (100%) rename pages/api/discovery/{seller => artist}/[sellerId]/portfolio.tsx (100%) rename pages/api/discovery/{sellers.tsx => artists.tsx} (100%) rename pages/{seller => artist}/[id].tsx (97%) rename pages/{seller => artist}/[id]/request.tsx (98%) create mode 100644 pages/artistDashboard.tsx delete mode 100644 pages/sellerDashboard.tsx diff --git a/components/artist.tsx b/components/artist.tsx index 38d93c9..4b0f4b6 100644 --- a/components/artist.tsx +++ b/components/artist.tsx @@ -26,7 +26,7 @@ const Artist = ({user, artistId}) => { const [sellerData, setSellerData] = useState([]); useEffect(() => { const getData = async () => { - const response = await fetch('/api/discovery/seller/'+artistId); + const response = await fetch('/api/discovery/artist/'+artistId); const data = await response.json(); setSellerData(data); } @@ -53,9 +53,9 @@ const Artist = ({user, artistId}) => { - + {user ? ( - + ) : ( diff --git a/components/artistPortfolio.tsx b/components/artistPortfolio.tsx index 193bbd6..18ac261 100644 --- a/components/artistPortfolio.tsx +++ b/components/artistPortfolio.tsx @@ -8,7 +8,7 @@ const ArtistPortfolio = ({artistId}) => { const [loading, setLoading] = useState(true); // State for loading indicator useEffect(() => { const getData = async () => { - const response = await fetch('/api/discovery/seller/'+artistId+'/portfolio'); + const response = await fetch('/api/discovery/artist/'+artistId+'/portfolio'); const data = await response.json(); setPortfolioData(data); setLoading(false); diff --git a/components/header.tsx b/components/header.tsx index 8a6f3f3..eed18f2 100644 --- a/components/header.tsx +++ b/components/header.tsx @@ -104,8 +104,8 @@ function ResponsiveAppBar() { open={Boolean(anchorElUser)} onClose={handleCloseUserMenu} > - - + + diff --git a/package-lock.json b/package-lock.json index d469261..6c0cdd0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,9 @@ "@mui/icons-material": "^5.15.6", "@mui/material": "^5.15.6", "@mui/x-data-grid": "^6.19.4", + "@mui/x-date-pickers": "^6.19.4", "@novu/notification-center": "^0.22.0", + "dayjs": "^1.11.10", "next": "latest", "openapi-typescript-fetch": "^1.1.3", "react": "^18.2.0", @@ -691,6 +693,71 @@ "react-dom": "^17.0.0 || ^18.0.0" } }, + "node_modules/@mui/x-date-pickers": { + "version": "6.19.4", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.19.4.tgz", + "integrity": "sha512-LekaacLGnoQNN5hD6iXeHFL4LbZPnr1BM57hnUKy5UgKDHqzHzZSdPGc2p7Ktv/Z2NDbpPaLEAgrLwISKIYcow==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@mui/base": "^5.0.0-beta.22", + "@mui/utils": "^5.14.16", + "@types/react-transition-group": "^4.4.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.8.6", + "@mui/system": "^5.8.0", + "date-fns": "^2.25.0 || ^3.2.0", + "date-fns-jalali": "^2.13.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", + "moment-hijri": "^2.1.2", + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "date-fns-jalali": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + }, + "moment-hijri": { + "optional": true + }, + "moment-jalaali": { + "optional": true + } + } + }, "node_modules/@next/env": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz", @@ -1374,6 +1441,11 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", diff --git a/package.json b/package.json index 91d9279..fae9ea5 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,9 @@ "@mui/icons-material": "^5.15.6", "@mui/material": "^5.15.6", "@mui/x-data-grid": "^6.19.4", + "@mui/x-date-pickers": "^6.19.4", "@novu/notification-center": "^0.22.0", + "dayjs": "^1.11.10", "next": "latest", "openapi-typescript-fetch": "^1.1.3", "react": "^18.2.0", diff --git a/pages/api/seller/request.tsx b/pages/api/artist/newRequest.tsx similarity index 100% rename from pages/api/seller/request.tsx rename to pages/api/artist/newRequest.tsx diff --git a/pages/api/artist/onboarded.tsx b/pages/api/artist/onboarded.tsx new file mode 100644 index 0000000..5216573 --- /dev/null +++ b/pages/api/artist/onboarded.tsx @@ -0,0 +1,14 @@ +import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0'; + +export default withApiAuthRequired(async function onboardUrl(req, res) { + const { accessToken } = await getAccessToken(req, res); + const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/SellerProfile/Onboard', { + headers: { + "Authorization": `Bearer ${accessToken}` + } + }); + + let result = await response.json(); + res.status(200).json(result); +}); + diff --git a/pages/api/artist/onboardurl.tsx b/pages/api/artist/onboardurl.tsx new file mode 100644 index 0000000..c7b624a --- /dev/null +++ b/pages/api/artist/onboardurl.tsx @@ -0,0 +1,14 @@ +import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0'; + +export default withApiAuthRequired(async function onboardUrl(req, res) { + const { accessToken } = await getAccessToken(req, res); + const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/SellerProfile/Onboard/Url', { + headers: { + "Authorization": `Bearer ${accessToken}` + } + }); + + let result = await response.json(); + res.status(200).json(result); +}); + diff --git a/pages/api/seller/profile.tsx b/pages/api/artist/profile.tsx similarity index 95% rename from pages/api/seller/profile.tsx rename to pages/api/artist/profile.tsx index 5b54203..af46463 100644 --- a/pages/api/seller/profile.tsx +++ b/pages/api/artist/profile.tsx @@ -1,7 +1,6 @@ import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0'; export default withApiAuthRequired(async function sellerProfile(req, res) { - console.log("TEST") const { accessToken } = await getAccessToken(req, res); const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/SellerProfile', { headers: { diff --git a/pages/api/artist/request.tsx b/pages/api/artist/request.tsx new file mode 100644 index 0000000..2006b13 --- /dev/null +++ b/pages/api/artist/request.tsx @@ -0,0 +1,20 @@ +import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0'; + +export default withApiAuthRequired(async function products(req, res) { + const { accessToken } = await getAccessToken(req, res); + const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/SellerProfile/Request', { + headers: { + "Authorization": `Bearer ${accessToken}` + }, + method: 'GET' + }); + if(response.status == 404) + { + res.status(200).json({}) + } + else{ + let result = await response.json(); + res.status(200).json(result); + } +}); + diff --git a/pages/api/discovery/seller/[sellerId].tsx b/pages/api/discovery/artist/[sellerId].tsx similarity index 100% rename from pages/api/discovery/seller/[sellerId].tsx rename to pages/api/discovery/artist/[sellerId].tsx diff --git a/pages/api/discovery/seller/[sellerId]/portfolio.tsx b/pages/api/discovery/artist/[sellerId]/portfolio.tsx similarity index 100% rename from pages/api/discovery/seller/[sellerId]/portfolio.tsx rename to pages/api/discovery/artist/[sellerId]/portfolio.tsx diff --git a/pages/api/discovery/sellers.tsx b/pages/api/discovery/artists.tsx similarity index 100% rename from pages/api/discovery/sellers.tsx rename to pages/api/discovery/artists.tsx diff --git a/pages/seller/[id].tsx b/pages/artist/[id].tsx similarity index 97% rename from pages/seller/[id].tsx rename to pages/artist/[id].tsx index 74d0135..731a49d 100644 --- a/pages/seller/[id].tsx +++ b/pages/artist/[id].tsx @@ -15,7 +15,7 @@ const SellerProfile = () => { useEffect(() => { const getData = async () => { if(id){ - const response = await fetch('/api/discovery/seller/'+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 @@ -82,7 +82,7 @@ const SellerProfile = () => { {user ? ( - ) : ( diff --git a/pages/seller/[id]/request.tsx b/pages/artist/[id]/request.tsx similarity index 98% rename from pages/seller/[id]/request.tsx rename to pages/artist/[id]/request.tsx index 21481c5..65e68d6 100644 --- a/pages/seller/[id]/request.tsx +++ b/pages/artist/[id]/request.tsx @@ -21,7 +21,7 @@ const SellerProfile = () => { useEffect(() => { const getData = async () => { if(id){ - const response = await fetch('/api/discovery/seller/'+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 diff --git a/pages/artistDashboard.tsx b/pages/artistDashboard.tsx new file mode 100644 index 0000000..54d4571 --- /dev/null +++ b/pages/artistDashboard.tsx @@ -0,0 +1,338 @@ +import { useUser } from "@auth0/nextjs-auth0/client"; +import { useTheme } from '@mui/material/styles'; +import AppBar from '@mui/material/AppBar'; +import Tabs from '@mui/material/Tabs'; +import Tab from '@mui/material/Tab'; +import Layout from "../components/layout"; +import { Grid, Button, Typography, TextField, Box, CircularProgress } from "@mui/material"; +import { useState, useEffect } from "react"; +import Card from '@mui/material/Card'; +import CardContent from '@mui/material/CardContent'; +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'; + + + + + +const SellerDashoard = (ctx) => { + const { user, isLoading } = useUser(); + const [sellerRequestData, setSellerRequestData] = useState([]); + const [sellerData, setSellerData] = useState([]); + const [loading, setLoading] = useState(true); // State for loading indicator + const [isOnboarded, setIsOnboarded] = useState(false); + const [onBoardUrl, setOnBoardUrl] = useState(""); + + const [tabValue, setTabValue] = useState(1); + + const getData = async () => { + const response = await fetch('/api/artist/profile'); + const sellerProfile = await response.json(); + setSellerData(sellerProfile); + const requestResponse = await fetch('/api/artist/request', { method: "GET" }); + const sellerRequest = await requestResponse.json(); + setSellerRequestData(sellerRequest); + const onboardCheckRequest = await fetch('/api/artist/onboarded', { method: "GET" }); + const onboardCheckResponse = await onboardCheckRequest.json(); + setIsOnboarded(onboardCheckResponse["onboarded"]); + const onboardUrlRequest = await fetch('/api/artist/onboardurl', { method: "GET" }); + const onboardUrlResponse = await onboardUrlRequest.json(); + setOnBoardUrl(onboardUrlResponse["onboardUrl"]); + + setLoading(false); // Once data is fetched, set loading to false + } + + const handleChange = (event: React.SyntheticEvent, newValue: number) => { + setTabValue(newValue); + }; + + const handleChangeIndex = (index: number) => { + setTabValue(index); + }; + + interface TabPanelProps { + children?: React.ReactNode; + dir?: string; + index: number; + value: number; + } + + function TabPanel(props: TabPanelProps) { + const { children, value, index, ...other } = props; + + return ( + + ); + } + + function a11yProps(index: number) { + return { + id: `full-width-tab-${index}`, + 'aria-controls': `full-width-tabpanel-${index}`, + }; + } + + + useEffect(() => { + getData(); + }, []); + const theme = useTheme(); + + const columns: GridColDef[] = [ + { field: 'requestor', headerName: 'User', width: 150 }, + { field: 'message', headerName: 'Message', width: 280 }, + { field: 'amount', headerName: 'Amount', width: 125 }, + ]; + const rows = [ + { id: 1, requestor: 'Snow', message: 'This is a test message!', amount: 35.00 }, + { id: 2, requestor: 'Lannister', message: 'This is a test message!', amount: 42.00 }, + { id: 3, requestor: 'Lannister', message: 'This is a test message!', amount: 45.00 }, + { id: 4, requestor: 'Stark', message: 'This is a test message!', amount: 16.00 }, + { id: 5, requestor: 'Targaryen', message: 'This is a test message!', amount: 150.00 }, + { id: 6, requestor: 'Melisandre', message: "This is a test message!", amount: 150.00 }, + { id: 7, requestor: 'Clifford', message: 'This is a test message!', amount: 44.00 }, + { id: 8, requestor: 'Frances', message: 'This is a test message!', amount: 36.00 }, + { id: 9, requestor: 'Roxie', message: 'This is a test message!', amount: 65.00 }, + ]; + + + let formattedTime = "" + if (sellerRequestData) { + const date = new Date(sellerRequestData["requestDate"]); + formattedTime = date.toLocaleTimeString('en-US', { month: 'long', day: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); // Example format + } + + const payoutButton = () =>{ + fetch('/api/artist/payout').then((response) => { + if (response.ok) { + fetch('/api/artist/request').then((requestResponse) => { + requestResponse.json().then((sellerRequest) => { + setSellerRequestData(sellerRequest); + }); + }); + } + }); + } + + const requestButton = () => { + fetch('/api/artist/newRequest').then((response) => { + if (response.ok) { + fetch('/api/artist/request').then((requestResponse) => { + requestResponse.json().then((sellerRequest) => { + setSellerRequestData(sellerRequest); + getData(); + }); + }); + } + }); + } + + return ( + <> + {loading ? ( // Render loading indicator if loading is true + + + Loading... + + + + ) : ( + + + + {(Object.keys(sellerData).length > 0 ? ( + <> + + + + + + + Artist Dashboard + + + + + + {(Object.keys(sellerRequestData).length > 0 ? ( + <> + + + + + Request Status + + {(sellerRequestData["accepted"] ? ( + Accepted + ) : ( + Pending + ))} + Request submitted on {formattedTime ?? ''} + + + + + + + + {(sellerRequestData["accepted"] ? ( + <> + + {(isOnboarded ? (<> + + + + ) : ( + <> + + + + ))} + + + + + + + + + + + + + + + + + Item Two + + + Item Three + + + + + ) : ( +<> ))} + + + ) : ( + <> + + {(Object.keys(sellerRequestData).length==0 || sellerRequestData["accepted"]==false ? (<>):(<>))} + + + ))} + + + ) : ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Item Two + + + Item Three + + + + + ))} + + + + )} + + ); +}; + +export default SellerDashoard; diff --git a/pages/index.tsx b/pages/index.tsx index 313712b..a6f7aef 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -9,7 +9,7 @@ const Home = () => { const [loading, setLoading] = useState(true); // State for loading indicator useEffect(() => { const getData = async () => { - const response = await fetch('/api/discovery/sellers'); + const response = await fetch('/api/discovery/artists'); const data = await response.json(); setSellersData(data); setLoading(false); diff --git a/pages/sellerDashboard.tsx b/pages/sellerDashboard.tsx deleted file mode 100644 index b6c1739..0000000 --- a/pages/sellerDashboard.tsx +++ /dev/null @@ -1,188 +0,0 @@ -import { useUser } from "@auth0/nextjs-auth0/client"; -import { useTheme } from '@mui/material/styles'; -import AppBar from '@mui/material/AppBar'; -import Tabs from '@mui/material/Tabs'; -import Tab from '@mui/material/Tab'; -import Layout from "../components/layout"; -import { Grid, Button, Typography, TextField, Box } from "@mui/material"; -import { useState, useEffect } from "react"; -import SwipeableViews from '../components/swipableView'; -import { DataGrid, GridColDef, GridValueGetterParams } from '@mui/x-data-grid'; - - - - - -const SellerDashoard = (ctx) => { - const { user, isLoading } = useUser(); - const [sellerRequestData, setSellerRequestData] = useState([]); - const [sellerData, setSellerData] = useState([]); - const [loading, setLoading] = useState(true); // State for loading indicator - - const [tabValue, setTabValue] = useState(0); - - const handleChange = (event: React.SyntheticEvent, newValue: number) => { - setTabValue(newValue); - }; - - const handleChangeIndex = (index: number) => { - setTabValue(index); - }; - - const requestSeller = () => { - const response = fetch('/api/seller/request', { - method: 'POST' - }).then((response) => { - console.log(response); - }); - } - - interface TabPanelProps { - children?: React.ReactNode; - dir?: string; - index: number; - value: number; - } - - function TabPanel(props: TabPanelProps) { - const { children, value, index, ...other } = props; - - return ( - - ); - } - - function a11yProps(index: number) { - return { - id: `full-width-tab-${index}`, - 'aria-controls': `full-width-tabpanel-${index}`, - }; - } - - - useEffect(() => { - const getData = async () => { - const response = await fetch('/api/seller/profile'); - const sellerProfile = await response.json(); - console.log(sellerProfile) - setSellerData(sellerProfile); - const requestResponse = await fetch('/api/seller/request', {method:"POST"}); - const sellerRequest = await response.json(); - setSellerData(sellerProfile); - setLoading(false); // Once data is fetched, set loading to false - } - getData(); - }, []); - const theme = useTheme(); - - const columns: GridColDef[] = [ - { field: 'requestor', headerName: 'User', width: 150 }, - { field: 'message', headerName: 'Message', width: 280 }, - { field: 'amount', headerName: 'Amount', width:125 }, - ]; - const rows = [ - { id: 1, requestor: 'Snow', message: 'This is a test message!', amount: 35.00 }, - { id: 2, requestor: 'Lannister', message: 'This is a test message!', amount: 42.00 }, - { id: 3, requestor: 'Lannister', message: 'This is a test message!', amount: 45.00 }, - { id: 4, requestor: 'Stark', message: 'This is a test message!', amount: 16.00 }, - { id: 5, requestor: 'Targaryen', message: 'This is a test message!', amount: 150.00 }, - { id: 6, requestor: 'Melisandre', message: "This is a test message!", amount: 150.00 }, - { id: 7, requestor: 'Clifford', message: 'This is a test message!', amount: 44.00 }, - { id: 8, requestor: 'Frances', message: 'This is a test message!', amount: 36.00 }, - { id: 9, requestor: 'Roxie', message: 'This is a test message!', amount: 65.00 }, - ]; - - - return ( - - - - - - - - - Seller Dashboard - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Item Two - - - Item Three - - - - - - ); -}; - -export default SellerDashoard;