diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..8d70e3d --- /dev/null +++ b/.env.development @@ -0,0 +1,9 @@ +AUTH0_ISSUER_BASE_URL="https://dev-12mb5yq82dow1twh.us.auth0.com" +AUTH0_CLIENT_ID="avpoVGBxJfr15m6d3BfTzsEH4v3yBXna" +AUTH0_CLIENT_SECRET="rCbTzrXdwZermb-N2GGqnCVI8YSTa32CA3GtuqZcmDRA6X0OGQGyiP4cRkhBSIsd" +AUTH0_BASE_URL="http://localhost:3000" +AUTH0_SECRET="rCbTzrXdwZermb-N2GGqnCVI8YSTa32CA3GtuqZcmDRA6X0OGQGyiP4cRkhBSIsd" +AUTH0_AUDIENCE="https://api.artplatform.com" +AUTH0_SCOPE="openid profile email read:user write:user read:billing-information write:billing-information read:seller-profile write:seller-profile read:seller-profile-request write:seller-profile-request read:seller-service write:seller-service read:orders write:orders read:seller-orders write:seller-orders" +NEXT_PUBLIC_API_URL="https://core-api.development.comissions.app" +REACT_EDITOR=atom diff --git a/.env.local.example b/.env.local.example deleted file mode 100644 index d27d0dd..0000000 --- a/.env.local.example +++ /dev/null @@ -1,5 +0,0 @@ -AUTH0_ISSUER_BASE_URL="https://" -AUTH0_CLIENT_ID= -AUTH0_CLIENT_SECRET= -AUTH0_BASE_URL="http://localhost:3000" -AUTH0_SECRET= \ No newline at end of file diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..2a549d2 --- /dev/null +++ b/.env.production @@ -0,0 +1,8 @@ +AUTH0_ISSUER_BASE_URL="https://dev-12mb5yq82dow1twh.us.auth0.com" +AUTH0_CLIENT_ID="avpoVGBxJfr15m6d3BfTzsEH4v3yBXna" +AUTH0_CLIENT_SECRET="rCbTzrXdwZermb-N2GGqnCVI8YSTa32CA3GtuqZcmDRA6X0OGQGyiP4cRkhBSIsd" +AUTH0_BASE_URL="http://localhost:3000" +AUTH0_SECRET="rCbTzrXdwZermb-N2GGqnCVI8YSTa32CA3GtuqZcmDRA6X0OGQGyiP4cRkhBSIsd" +AUTH0_SCOPE="openid profile email read:user write:user read:billing-information write:billing-information read:seller-profile write:seller-profile read:seller-profile-request write:seller-profile-request read:seller-service write:seller-service read:orders write:orders read:seller-orders write:seller-orders" +NEXT_PUBLIC_API_URL="https://core-api.development.comissions.app" +REACT_EDITOR=atom diff --git a/components/artist.tsx b/components/artist.tsx index 90755df..38d93c9 100644 --- a/components/artist.tsx +++ b/components/artist.tsx @@ -18,7 +18,6 @@ import ArtistPortfolio from './artistPortfolio'; import Button from '@mui/material/Button'; import Tooltip from '@mui/material/Tooltip'; import { useEffect, useState } from "react"; -import { fetchSeller } from "../services/DiscoveryService"; import { IconButton } from '@mui/material'; @@ -27,8 +26,8 @@ const Artist = ({user, artistId}) => { const [sellerData, setSellerData] = useState([]); useEffect(() => { const getData = async () => { - const data = await fetchSeller(artistId); - console.log(data) + const response = await fetch('/api/discovery/seller/'+artistId); + const data = await response.json(); setSellerData(data); } getData(); @@ -56,7 +55,7 @@ const Artist = ({user, artistId}) => { <Grid item xs={6} md={4}> <Button href={"seller/"+artistId} color="primary" variant='contained' sx={{width:160}}>View Profile</Button> {user ? ( - <Button color="secondary" variant='contained' sx={{ width: 160, marginTop:2 }}>Submit Request</Button> + <Button color="secondary" variant='contained' href={"/seller/"+artistId+"/request"} sx={{ width: 160, marginTop:2 }}>Submit Request</Button> ) : ( <Tooltip title="Log in order to place a request."> <span> diff --git a/components/artistPortfolio.tsx b/components/artistPortfolio.tsx index 7863f39..193bbd6 100644 --- a/components/artistPortfolio.tsx +++ b/components/artistPortfolio.tsx @@ -1,30 +1,37 @@ import * as React from 'react'; -import ImageList from '@mui/material/ImageList'; -import ImageListItem from '@mui/material/ImageListItem'; +import {ImageList, Box, Typography, CircularProgress} from '@mui/material'; import { useEffect, useState } from "react"; -import { fetchSellerPortfolio,getPortfolioUrl } from "../services/DiscoveryService"; import ArtistPortfolioImage from './artistPortfolioImage'; - -import { IconButton } from '@mui/material'; - const ArtistPortfolio = ({artistId}) => { const [portfolioData, setPortfolioData] = useState([]); + const [loading, setLoading] = useState(true); // State for loading indicator useEffect(() => { const getData = async () => { - const data = await fetchSellerPortfolio(artistId); - console.log(data) + const response = await fetch('/api/discovery/seller/'+artistId+'/portfolio'); + const data = await response.json(); setPortfolioData(data); + setLoading(false); } + console.log(portfolioData) getData(); }, []); - return ( - - <ImageList cols={2} rowHeight={200} sx={{maxHeight:400}}> - {portfolioData.map((item) => ( - <ArtistPortfolioImage artistId={artistId} itemId={item.id} /> - ))} - </ImageList>) + (loading) ? ( + <Box sx={{textAlign:"center", paddingTop:20}}> + <Typography variant="h4" sx={{textAlign:"center"}}> + Loading... + </Typography> + <CircularProgress sx={{paddingTop:5}} /> + </Box> + ) : + ( + <ImageList cols={2} rowHeight={200} sx={{maxHeight:400}}> + {portfolioData.map((item) => ( + <ArtistPortfolioImage artistId={artistId} itemId={item.id} /> + ))} + </ImageList> + ) + ) } export default ArtistPortfolio \ No newline at end of file diff --git a/components/artistPortfolioImage.tsx b/components/artistPortfolioImage.tsx index 6a30464..55e6900 100644 --- a/components/artistPortfolioImage.tsx +++ b/components/artistPortfolioImage.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import ImageList from '@mui/material/ImageList'; import ImageListItem from '@mui/material/ImageListItem'; import { useEffect, useState } from "react"; -import { fetchSellerPortfolio,getPortfolioUrl } from "../services/DiscoveryService"; import { CircularProgress } from '@mui/material'; @@ -13,21 +12,12 @@ const ArtistPortfolioImage = ({artistId,itemId}) => { const handleImageLoaded = () => { setLoaded(true); }; - const [portfolioData, setPortfolioData] = useState([]); - useEffect(() => { - const getData = async () => { - const data = await fetchSellerPortfolio(artistId); - console.log(data) - setPortfolioData(data); - } - getData(); - }, []); return ( <ImageListItem key={itemId }> <img - srcSet={`${getPortfolioUrl(artistId,itemId)}`} - src={`${getPortfolioUrl(artistId,itemId)}`} + 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' }} diff --git a/components/header.tsx b/components/header.tsx index e0cb648..8a6f3f3 100644 --- a/components/header.tsx +++ b/components/header.tsx @@ -105,7 +105,7 @@ function ResponsiveAppBar() { onClose={handleCloseUserMenu} > <MenuItem key="sellerDashboard" onClick={handleCloseUserMenu}> - <Button fullWidth color="secondary" variant='contained' href="/profile">Seller Dashboard</Button> + <Button fullWidth color="secondary" variant='contained' href="/sellerDashboard">Seller Dashboard</Button> </MenuItem> <MenuItem key="myOrders" onClick={handleCloseUserMenu}> <Button fullWidth color="primary" href="profile">My Orders</Button> diff --git a/pages/api/discovery/seller/[sellerId].tsx b/pages/api/discovery/seller/[sellerId].tsx new file mode 100644 index 0000000..05680f8 --- /dev/null +++ b/pages/api/discovery/seller/[sellerId].tsx @@ -0,0 +1,13 @@ +import { useRouter } from 'next/router' + + +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}`; + const response = await fetch(url); + if (!response.ok) { + throw new Error('Failed to fetch seller'); + } + let result = await response.json(); + res.status(200).json(result); +} \ No newline at end of file diff --git a/pages/api/discovery/seller/[sellerId]/portfolio.tsx b/pages/api/discovery/seller/[sellerId]/portfolio.tsx new file mode 100644 index 0000000..1845650 --- /dev/null +++ b/pages/api/discovery/seller/[sellerId]/portfolio.tsx @@ -0,0 +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) + const response = await fetch(url); + if (!response.ok) { + throw new Error('Failed to fetch seller portfolio'); + } + var result = await response.json(); + console.log(result) + res.status(200).json(result); +} + diff --git a/pages/api/discovery/sellers.tsx b/pages/api/discovery/sellers.tsx new file mode 100644 index 0000000..30c0889 --- /dev/null +++ b/pages/api/discovery/sellers.tsx @@ -0,0 +1,9 @@ +export default async function handler(req, res): Promise<any> { + let url = process.env.NEXT_PUBLIC_API_URL+`/api/Discovery/Sellers`; + const response = await fetch(url); + if (!response.ok) { + throw new Error('Failed to fetch sellers'); + } + let parsedJson = await response.json(); + res.status(200).json(parsedJson); +} \ No newline at end of file diff --git a/pages/api/protected-api.ts b/pages/api/protected-api.ts deleted file mode 100644 index b33602c..0000000 --- a/pages/api/protected-api.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { withApiAuthRequired, getSession } from "@auth0/nextjs-auth0"; - -// Serverless function -// Protected API, requests to '/api/protected' without a valid session cookie will fail - -async function handle(req, res) { - const { user } = await getSession(req, res); - - try { - res.status(200).json({ - session: "true", - id: user.sub, - nickname: user.nickname, - }); - } catch (e) { - res.status(500).json({ error: "Unable to fetch", description: e }); - } -} - -export default withApiAuthRequired(handle); diff --git a/pages/api/sellers/profile.tsx b/pages/api/sellers/profile.tsx new file mode 100644 index 0000000..038ca6e --- /dev/null +++ b/pages/api/sellers/profile.tsx @@ -0,0 +1,20 @@ +import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0'; + +export default withApiAuthRequired(async function products(req, res) { + // If your Access Token is expired and you have a Refresh Token + // `getAccessToken` will fetch you a new one using the `refresh_token` grant + const { accessToken } = await getAccessToken(req, res); + const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/SellerProfile', { + headers: { + "Authorization": `Bearer ${accessToken}` + } + }); + if(response.status == 401 || response.status == 400){ + res.status(200); + } + else{ + let result = await response.json(); + res.status(200).json(result); + } +}); + diff --git a/pages/index.tsx b/pages/index.tsx index c626926..313712b 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,55 +1,22 @@ import { useUser } from "@auth0/nextjs-auth0/client"; -import { GetAccessToken } from "@auth0/nextjs-auth0"; import Layout from "../components/layout"; -import TextField from '@mui/material/TextField'; -import Button from '@mui/material/Button'; -import { Typography } from "@mui/material"; -import Box from '@mui/material/Box'; -import ButtonGroup from '@mui/material/ButtonGroup'; -import styled from "@emotion/styled"; +import { Typography, Box, CircularProgress } from '@mui/material'; import Artist from "../components/artist"; import { useEffect, useState } from "react"; -import { fetchSellers } from "../services/DiscoveryService"; -import CircularProgress from '@mui/material/CircularProgress'; - - -const StyledTextField = styled(TextField)({ - "& .MuiInputLabel-root": { - right: 0, - textAlign: "center" - }, - "& .MuiInputLabel-shrink": { - margin: "0 auto", - position: "absolute", - right: "0", - left: "0", - top: "-3px", - width: "150px", // Need to give it a width so the positioning will work - background: "white" // Add a white background as below we remove the legend that had the background so text is not meshing with the border - // display: "none" //if you want to hide it completly - }, - "& .MuiOutlinedInput-root.Mui-focused": { - "& legend ": { - display: "none" - } - } -}); - const Home = () => { const [sellersData, setSellersData] = useState([]); const [loading, setLoading] = useState(true); // State for loading indicator useEffect(() => { const getData = async () => { - const data = await fetchSellers(); + const response = await fetch('/api/discovery/sellers'); + const data = await response.json(); setSellersData(data); setLoading(false); } getData(); }, []); - const { user, isLoading } = useUser(); - return ( <Layout user={user} loading={isLoading}> {loading ? ( // Render loading indicator if loading is true @@ -71,16 +38,4 @@ const Home = () => { }; // fast/cached SSR page -export default Home; - - -const chips = [ - { label: 'Category', outlined: true }, - { label: 'Category', outlined: false }, - { label: 'Category', outlined: true }, - { label: 'Category', outlined: false }, - { label: 'Category', outlined: true }, - { label: 'Category', outlined: false }, - { label: 'Category', outlined: true }, - { label: 'Category', outlined: false }, -]; \ No newline at end of file +export default Home; \ No newline at end of file diff --git a/pages/seller/[id].tsx b/pages/seller/[id].tsx index e4254dc..74d0135 100644 --- a/pages/seller/[id].tsx +++ b/pages/seller/[id].tsx @@ -1,33 +1,22 @@ import Layout from "../../components/layout"; import { useUser } from "@auth0/nextjs-auth0/client"; -import { Box, Grid, Card, CardContent, Typography, List, ListItem, ListItemButton, ListItemIcon, - ListItemText, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Button, - Tabs, Tab, CircularProgress } from "@mui/material"; +import { Box, Grid, Card, CardContent, Typography, List, Button, CircularProgress, Tooltip } from "@mui/material"; import { useState, useEffect } from "react"; import { useRouter } from 'next/router' -import { fetchSeller } from "../../services/DiscoveryService"; import ArtistPortfolio from "../../components/artistPortfolio"; -import Tooltip from '@mui/material/Tooltip'; -import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; -interface TabPanelProps { - children?: React.ReactNode; - index: number; - value: number; -} - const SellerProfile = () => { const { user, isLoading } = useUser(); const router = useRouter() const { id } = router.query - console.log(router.query) const [sellerData, setSellerData] = useState([]); const [loading, setLoading] = useState(true); // State for loading indicator useEffect(() => { const getData = async () => { if(id){ - const data = await fetchSeller(id); + const response = await fetch('/api/discovery/seller/'+id); + const data = await response.json(); setSellerData(data); setLoading(false); // Once data is fetched, set loading to false } @@ -35,10 +24,6 @@ const SellerProfile = () => { getData(); }, [id]); - const handleChange = (event: React.SyntheticEvent, newValue: number) => { - setValue(newValue); - }; - const [value, setValue] = useState(0); return ( <Layout user={user} loading={isLoading}> diff --git a/pages/seller/[id]/request.tsx b/pages/seller/[id]/request.tsx index 4b00e0d..21481c5 100644 --- a/pages/seller/[id]/request.tsx +++ b/pages/seller/[id]/request.tsx @@ -1,15 +1,8 @@ import Layout from "../../../components/layout"; import { useUser } from "@auth0/nextjs-auth0/client"; -import { Box, Grid, Card, CardContent, Typography, List, ListItem, ListItemButton, ListItemIcon, - ListItemText, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Button, - Tabs, Tab, CircularProgress } from "@mui/material"; +import { Box, Grid, Typography, Button, CircularProgress, TextField} from "@mui/material"; import { useState, useEffect } from "react"; import { useRouter } from 'next/router' -import { fetchSeller } from "../../../services/DiscoveryService"; -import ArtistPortfolio from "../../../components/artistPortfolio"; -import Tooltip from '@mui/material/Tooltip'; -import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; -import { TextField } from "@mui/material"; import CurrencyTextField from '@lupus-ai/mui-currency-textfield' interface TabPanelProps { @@ -19,16 +12,17 @@ interface TabPanelProps { } const SellerProfile = () => { + const { user, isLoading } = useUser(); const router = useRouter() const { id } = router.query - console.log(router.query) const [sellerData, setSellerData] = useState([]); const [loading, setLoading] = useState(true); // State for loading indicator useEffect(() => { const getData = async () => { if(id){ - const data = await fetchSeller(id); + const response = await fetch('/api/discovery/seller/'+id); + const data = await response.json(); setSellerData(data); setLoading(false); // Once data is fetched, set loading to false } diff --git a/pages/sellerDashboard.tsx b/pages/sellerDashboard.tsx new file mode 100644 index 0000000..7affeb3 --- /dev/null +++ b/pages/sellerDashboard.tsx @@ -0,0 +1,87 @@ +import { useUser } from "@auth0/nextjs-auth0/client"; +import { getAccessToken } from "@auth0/nextjs-auth0"; +import Layout from "../components/layout"; +import { Grid, Button, Typography, TextField, Box } from "@mui/material"; +import { useState, useEffect } from "react"; + + + + +const SellerDashoard = (ctx) => { + const { user, isLoading } = useUser(); + const [sellerData, setSellerData] = useState([]); + const [loading, setLoading] = useState(true); // State for loading indicator + useEffect(() => { + const getData = async () => { + const response = await fetch('/api/sellers/profile'); + const sellerProfile = await response.json(); + setSellerData(sellerProfile); + setLoading(false); // Once data is fetched, set loading to false + } + getData(); + }, []); + return ( + <Layout user={user} loading={isLoading}> + + {(Object.keys(sellerData).length>0) ? ( + <><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"> + Seller Dashboard + </Typography> + </Grid> + <Grid item xs={12} sm={2} sx={{textAlign:"center"}}> + </Grid> + </Grid> + <Grid item xs={12} sm={12}> + </Grid> + </Grid> + <Grid container spacing={2} sx={{padding:4}}> + <Grid container sx={{textAlign:"center"}}> + <Grid item xs={12} sm={2} sx={{textAlign:"center"}}> + </Grid> + <Grid item xs={12} sm={8} sx={{textAlign:"center"}}> + TODO + </Grid> + <Grid item xs={12} sm={2} sx={{textAlign:"center"}}> + </Grid> + </Grid> + <Grid item xs={12} sm={12}> + </Grid> + </Grid> + </> + + ) : ( + <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"> + <Button size="large" color="secondary" variant="contained">Request To Become Seller</Button> + </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}> + </Grid> + </Grid> + )} + </Layout> + ); +}; + +export default SellerDashoard; diff --git a/pages/theme.ts b/pages/theme.ts deleted file mode 100644 index e69de29..0000000 diff --git a/services/DiscoveryService.ts b/services/DiscoveryService.ts index 589f39f..cd143bd 100644 --- a/services/DiscoveryService.ts +++ b/services/DiscoveryService.ts @@ -1,29 +1,11 @@ -export async function fetchSellers(): Promise<any> { - const baseUrl = "https://core-api.development.comissions.app"; - var url = baseUrl+`/api/Discovery/Sellers`; - console.log(url); - const response = await fetch(url); - if (!response.ok) { - throw new Error('Failed to fetch sellers'); - } - return await response.json(); -} -export async function fetchSeller(id): Promise<any> { - const baseUrl = "https://core-api.development.comissions.app"; - var url = baseUrl+`/api/Discovery/Sellers/${id}`; - const response = await fetch(url); - if (!response.ok) { - throw new Error('Failed to fetch seller'); - } - return await response.json(); -} + export async function fetchSellerPortfolio(id): Promise<any> { - const baseUrl = "https://core-api.development.comissions.app"; - var url = baseUrl+`/api/Discovery/Sellers/${id}/Portfolio`; + + var url = process.env.NEXT_PUBLIC_API_URL+`/api/Discovery/Sellers/${id}/Portfolio`; const response = await fetch(url); if (!response.ok) { throw new Error('Failed to fetch seller portfolio'); @@ -32,8 +14,8 @@ export async function fetchSellerPortfolio(id): Promise<any> { } export async function fetchServicePortfolio(sellerId, serviceId): Promise<any> { - const baseUrl = "https://core-api.development.comissions.app"; - var url = baseUrl+`/api/Discovery/Sellers/${sellerId}/Services/${serviceId}/Portfolio`; + + var url = process.env.NEXT_PUBLIC_API_URL+`/api/Discovery/Sellers/${sellerId}/Services/${serviceId}/Portfolio`; const response = await fetch(url); if (!response.ok) { throw new Error('Failed to fetch seller portfolio'); @@ -42,8 +24,8 @@ export async function fetchServicePortfolio(sellerId, serviceId): Promise<any> { } export async function fetchService(sellerId, serviceId): Promise<any> { - const baseUrl = "https://core-api.development.comissions.app"; - var url = baseUrl+`/api/Discovery/Sellers/${sellerId}/Services/${serviceId}`; + + var url = process.env.NEXT_PUBLIC_API_URL+`/api/Discovery/Sellers/${sellerId}/Services/${serviceId}`; const response = await fetch(url); if (!response.ok) { throw new Error('Failed to fetch seller portfolio'); @@ -53,7 +35,7 @@ export async function fetchService(sellerId, serviceId): Promise<any> { export function getPortfolioUrl(id, pieceId): string { - const baseUrl = "https://core-api.development.comissions.app"; - var url = baseUrl+`/api/Discovery/Sellers/${id}/Portfolio/${pieceId}`; + + var url = process.env.NEXT_PUBLIC_API_URL+`/api/Discovery/Sellers/${id}/Portfolio/${pieceId}`; return url; } \ No newline at end of file