mirror of
https://github.com/D4M13N-D3V/comissions-app-ui.git
synced 2025-03-14 08:15:08 +00:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
01cc7eb197 | |||
2d4663ef74 | |||
![]() |
0807d6d11d | ||
![]() |
2a405067d8 | ||
![]() |
23ea8eed79 | ||
![]() |
8569290c0e | ||
![]() |
5a2f43768d | ||
![]() |
ff465278ad |
@ -10,8 +10,7 @@ import Typography from '@mui/material/Typography';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import Drawer from '@mui/material/Drawer';
|
||||
import MenuIcon from '@mui/icons-material/Menu';
|
||||
import ToggleColorMode from './ToggleColorMode';
|
||||
import { ArrowLeftOutlined, ArrowRightRounded, Logout, OpenInNew } from '@mui/icons-material';
|
||||
import { Logout, OpenInNew } from '@mui/icons-material';
|
||||
|
||||
const logoStyle = {
|
||||
width: '140px',
|
||||
|
@ -9,7 +9,7 @@ import { useEffect, useState } from "react";
|
||||
|
||||
|
||||
|
||||
export default function ArtistRequest({id,userid,username,message,date,reload}) {
|
||||
export default function AdminArtistRequest({id,userid,username,message,date,reload}) {
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -4,10 +4,6 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
||||
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
||||
import { useRouter } from 'next/router';
|
||||
import { Rating } from '@mui/material';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import CurrencyTextField from '@lupus-ai/mui-currency-textfield';
|
||||
import { DateField } from '@mui/x-date-pickers';
|
||||
|
||||
export default function Reviews({artistId}) {
|
||||
const router = useRouter();
|
||||
@ -30,15 +26,19 @@ export default function Reviews({artistId}) {
|
||||
const getReviews = async () => {
|
||||
setIsLoading(true);
|
||||
const response = await fetch('/api/discovery/artist/'+artistId+'/reviews', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
});
|
||||
const data = await response.json();
|
||||
setReviewData(data);
|
||||
// Assuming your API returns an array under a key like 'reviews'
|
||||
// Adjust this according to your actual API response structure
|
||||
const rows = data.reviews || []; // If 'reviews' doesn't exist, default to an empty array
|
||||
setReviewData(rows);
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
||||
const getReviewsCount = async () => {
|
||||
const response = await fetch('/api/discovery/artist/'+artistId+'/reviewscount', {
|
||||
method: 'GET',
|
||||
|
@ -13,11 +13,14 @@ import PriceCheckIcon from '@mui/icons-material/PriceCheck';
|
||||
import AssignmentTurnedInIcon from '@mui/icons-material/AssignmentTurnedIn';
|
||||
import AssignmentLateIcon from '@mui/icons-material/AssignmentLate';
|
||||
import { useEffect, useState } from "react";
|
||||
import { useMediaQuery } from '@mui/material';
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
|
||||
export default function CustomerOrders() {
|
||||
const isSmallScreen = useMediaQuery(theme => theme.breakpoints.down('sm')); // Check if the screen size is small
|
||||
|
||||
const columns = [
|
||||
{ field: 'id', headerName: 'ID', flex: 0.1},
|
||||
{ field: 'status', headerName: 'Status', flex: 0.15,
|
||||
@ -42,12 +45,15 @@ export default function CustomerOrders() {
|
||||
}
|
||||
}
|
||||
},
|
||||
{ field: 'amount', headerName: 'Amount', flex: 0.1, renderCell: (params) => {
|
||||
{ field: 'amount', headerName: '$', flex: 0.1, renderCell: (params) => {
|
||||
return <CurrencyTextField size="small" fullWidth value={params.row.amount} currencySymbol="$" disabled />;
|
||||
}},
|
||||
{ field: 'requestDate', headerName: 'Request Date', flex:0.15, type: 'date' ,
|
||||
valueGetter: (params) => { return new Date(params.row.requestDate); }}
|
||||
];
|
||||
if(!isSmallScreen){
|
||||
columns.push(
|
||||
{ field: 'requestDate', headerName: 'Request Date', flex:0.15, type: 'date' ,
|
||||
valueGetter: (params) => { return new Date(params.row.requestDate); }} );
|
||||
}
|
||||
const [isLoading, setIsLoading] = React.useState(true);
|
||||
const [requestCount, setRequestCount] = React.useState(null);
|
||||
const [requestData, setRequestData] = React.useState({});
|
||||
|
0
components/test.tsx
Normal file
0
components/test.tsx
Normal file
@ -61,7 +61,6 @@ const VerticalNavHeader = (props: Props) => {
|
||||
) : (
|
||||
<Link href='/' passHref>
|
||||
<StyledLink>
|
||||
<img width={30} height={25} src= "https://s6.imgcdn.dev/ttLwl.png"/>
|
||||
<HeaderTitle variant='h6' sx={{ ml: 3 }}>
|
||||
{themeConfig.templateName}
|
||||
</HeaderTitle>
|
||||
|
@ -8,16 +8,22 @@ import ListIcon from '@mui/icons-material/List';
|
||||
// ** Type import
|
||||
import { VerticalNavItemsType } from '../../core/layouts/types'
|
||||
import { BankTransfer, Cart, Clipboard, PageFirst, StarOutline } from 'mdi-material-ui'
|
||||
import { DocumentScanner, FileOpen, OpenInBrowser, Settings, WebAsset } from '@mui/icons-material'
|
||||
import { DocumentScanner, FileOpen, LockPerson, OpenInBrowser, People, PeopleOutline, Settings, WebAsset } from '@mui/icons-material'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
const navigation = (): VerticalNavItemsType => {
|
||||
const [isStripeOnboarded, setIsStripeOnboarded] = useState(false);
|
||||
const [profileData, setProfileData] = useState(null);
|
||||
const [userData, setUserData] = useState(null);
|
||||
const [isAdmin, setIsAdmin] = useState(false);
|
||||
|
||||
const getData = async () => {
|
||||
|
||||
const adminCheck = await fetch('/api/admin/check', { method: "GET" });
|
||||
if (adminCheck.status === 200) {
|
||||
setIsAdmin(true);
|
||||
}
|
||||
|
||||
const onboardCheckRequest = await fetch('/api/artist/onboarded', { method: "GET" });
|
||||
const onboardCheckResponse = await onboardCheckRequest.json();
|
||||
setIsStripeOnboarded(onboardCheckResponse["onboarded"]);
|
||||
@ -42,14 +48,6 @@ const navigation = (): VerticalNavItemsType => {
|
||||
icon: HomeOutline,
|
||||
path: '/dashboard'
|
||||
},
|
||||
{
|
||||
sectionTitle: 'Admin'
|
||||
},
|
||||
{
|
||||
title: 'Artist Requests',
|
||||
icon: Clipboard,
|
||||
path: '/dashboard/admin/requests'
|
||||
},
|
||||
{
|
||||
sectionTitle: 'General'
|
||||
},
|
||||
@ -65,6 +63,29 @@ const navigation = (): VerticalNavItemsType => {
|
||||
}
|
||||
];
|
||||
|
||||
if (isAdmin) {
|
||||
result.push(
|
||||
{
|
||||
sectionTitle: 'Admin'
|
||||
},
|
||||
{
|
||||
title: 'Manage Artist Access',
|
||||
icon: LockPerson,
|
||||
path: '/dashboard/admin/requests'
|
||||
},
|
||||
{
|
||||
title: 'Manage Users',
|
||||
icon: People,
|
||||
path: '/dashboard/admin/users'
|
||||
},
|
||||
{
|
||||
title: 'Manage Artists',
|
||||
icon: PeopleOutline,
|
||||
path: '/dashboard/admin/artists'
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (isStripeOnboarded) {
|
||||
result.push(
|
||||
{
|
||||
|
@ -1,103 +0,0 @@
|
||||
// ** React Imports
|
||||
import { SyntheticEvent, useState } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import Card from '@mui/material/Card'
|
||||
import TabList from '@mui/lab/TabList'
|
||||
import TabPanel from '@mui/lab/TabPanel'
|
||||
import TabContext from '@mui/lab/TabContext'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import MuiTab, { TabProps } from '@mui/material/Tab'
|
||||
|
||||
// ** Icons Imports
|
||||
import AccountOutline from 'mdi-material-ui/AccountOutline'
|
||||
import LockOpenOutline from 'mdi-material-ui/LockOpenOutline'
|
||||
import InformationOutline from 'mdi-material-ui/InformationOutline'
|
||||
|
||||
// ** Demo Tabs Imports
|
||||
import TabInfo from '../../views/account-settings/TabInfo'
|
||||
import TabAccount from '../../views/account-settings/TabAccount'
|
||||
import TabSecurity from '../../views/account-settings/TabSecurity'
|
||||
|
||||
// ** Third Party Styles Imports
|
||||
import 'react-datepicker/dist/react-datepicker.css'
|
||||
|
||||
const Tab = styled(MuiTab)<TabProps>(({ theme }) => ({
|
||||
[theme.breakpoints.down('md')]: {
|
||||
minWidth: 100
|
||||
},
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
minWidth: 67
|
||||
}
|
||||
}))
|
||||
|
||||
const TabName = styled('span')(({ theme }) => ({
|
||||
lineHeight: 1.71,
|
||||
fontSize: '0.875rem',
|
||||
marginLeft: theme.spacing(2.4),
|
||||
[theme.breakpoints.down('md')]: {
|
||||
display: 'none'
|
||||
}
|
||||
}))
|
||||
|
||||
const AccountSettings = () => {
|
||||
// ** State
|
||||
const [value, setValue] = useState<string>('account')
|
||||
|
||||
const handleChange = (event: SyntheticEvent, newValue: string) => {
|
||||
setValue(newValue)
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<TabContext value={value}>
|
||||
<TabList
|
||||
onChange={handleChange}
|
||||
aria-label='account-settings tabs'
|
||||
sx={{ borderBottom: theme => `1px solid ${theme.palette.divider}` }}
|
||||
>
|
||||
<Tab
|
||||
value='account'
|
||||
label={
|
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<AccountOutline />
|
||||
<TabName>Account</TabName>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<Tab
|
||||
value='security'
|
||||
label={
|
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<LockOpenOutline />
|
||||
<TabName>Security</TabName>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<Tab
|
||||
value='info'
|
||||
label={
|
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<InformationOutline />
|
||||
<TabName>Info</TabName>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
</TabList>
|
||||
|
||||
<TabPanel sx={{ p: 0 }} value='account'>
|
||||
<TabAccount />
|
||||
</TabPanel>
|
||||
<TabPanel sx={{ p: 0 }} value='security'>
|
||||
<TabSecurity />
|
||||
</TabPanel>
|
||||
<TabPanel sx={{ p: 0 }} value='info'>
|
||||
<TabInfo />
|
||||
</TabPanel>
|
||||
</TabContext>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default AccountSettings
|
@ -1,37 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useUser } from "@auth0/nextjs-auth0/client";
|
||||
import Layout from "../../components/Old/layout";
|
||||
|
||||
const ApiProfile = () => {
|
||||
const { user, isLoading } = useUser();
|
||||
|
||||
const [data, setData] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const res = await fetch("/api/protected-api");
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
setData(data);
|
||||
})();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Layout user={user} loading={isLoading}>
|
||||
<h1>Profile</h1>
|
||||
|
||||
<div>
|
||||
<h3>Public page (client rendered)</h3>
|
||||
<p>We are fetching data on the client-side :</p>
|
||||
<p>By making request to '/api/protected-api' serverless function</p>
|
||||
<p>so without a valid session cookie will fail</p>
|
||||
<p>{JSON.stringify(data)}</p>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
// Public route.(CSR) also accessing API from the client-side.
|
||||
// data is not cached when redirecting between pages.
|
||||
export default ApiProfile;
|
@ -1,26 +0,0 @@
|
||||
import { withPageAuthRequired } from "@auth0/nextjs-auth0";
|
||||
import Layout from "../../components/Old/layout";
|
||||
import { User } from "../../interfaces";
|
||||
|
||||
type ProfileProps = {
|
||||
user: User;
|
||||
};
|
||||
|
||||
export default function Profile({ user }: ProfileProps) {
|
||||
return (
|
||||
<Layout user={user}>
|
||||
<h1>Profile</h1>
|
||||
|
||||
<div>
|
||||
<h3>Profile (server rendered)</h3>
|
||||
<img src={user.picture} alt="user picture" />
|
||||
<p>nickname: {user.nickname}</p>
|
||||
<p>name: {user.name}</p>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
// Protected route, checking authentication status before rendering the page.(SSR)
|
||||
// It's slower than a static page with client side authentication
|
||||
export const getServerSideProps = withPageAuthRequired();
|
18
pages/api/admin/artists.tsx
Normal file
18
pages/api/admin/artists.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { offset, pageSize } = req.body;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminArtists?offset='+offset+'&pageSize='+pageSize, {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
return;
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
||||
|
18
pages/api/admin/artists/[artistId].tsx
Normal file
18
pages/api/admin/artists/[artistId].tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { artistId } = req.query;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminArtists/'+artistId, {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
return;
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function onboardUrl(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { userId } = req.query;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminArtistRequests/'+userId, {
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminArtists/'+userId+"/Suspend", {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`,
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
},
|
||||
method: req.method
|
||||
});
|
19
pages/api/admin/artists/[artistId]/terminate.tsx
Normal file
19
pages/api/admin/artists/[artistId]/terminate.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { userId } = req.query;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminArtists/'+userId+"/Terminate", {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
},
|
||||
method: req.method
|
||||
});
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
return;
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
||||
|
19
pages/api/admin/artists/[artistId]/unsuspend.tsx
Normal file
19
pages/api/admin/artists/[artistId]/unsuspend.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { userId } = req.query;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminArtists/'+userId+"/Unsuspend", {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
},
|
||||
method: req.method
|
||||
});
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
return;
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
||||
|
16
pages/api/admin/artists/count.tsx
Normal file
16
pages/api/admin/artists/count.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminArtists/Count', {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
return;
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
12
pages/api/admin/check.tsx
Normal file
12
pages/api/admin/check.tsx
Normal file
@ -0,0 +1,12 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminArtistRequests', {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
res.status(response.status).json({})
|
||||
});
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function onboardUrl(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminArtistRequests', {
|
||||
const { offset, pageSize } = req.body;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminArtistRequests?offset='+offset+'&pageSize='+pageSize, {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
}
|
||||
|
17
pages/api/admin/requests/[requestId].tsx
Normal file
17
pages/api/admin/requests/[requestId].tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { requestId } = req.query;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminArtistRequests/'+requestId, {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`,
|
||||
},
|
||||
method: req.method
|
||||
});
|
||||
console.log(response)
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
||||
|
||||
// handles ACCEPT AND DENY
|
16
pages/api/admin/requests/count.tsx
Normal file
16
pages/api/admin/requests/count.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminArtistRequests/Count', {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
return;
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
18
pages/api/admin/users.tsx
Normal file
18
pages/api/admin/users.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { offset, pageSize } = req.body;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminUsers?offset='+offset+'&pageSize='+pageSize, {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
return;
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
||||
|
18
pages/api/admin/users/[userId].tsx
Normal file
18
pages/api/admin/users/[userId].tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { userId } = req.query;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminUsers/'+userId, {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
return;
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
||||
|
19
pages/api/admin/users/[userId]/ban.tsx
Normal file
19
pages/api/admin/users/[userId]/ban.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { userId } = req.query;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminUsers/'+userId+"/Ban", {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
},
|
||||
method: req.method
|
||||
});
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
return;
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
||||
|
19
pages/api/admin/users/[userId]/suspend.tsx
Normal file
19
pages/api/admin/users/[userId]/suspend.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { userId } = req.query;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminUsers/'+userId+"/Suspend", {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
},
|
||||
method: req.method
|
||||
});
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
return;
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
||||
|
19
pages/api/admin/users/[userId]/unban.tsx
Normal file
19
pages/api/admin/users/[userId]/unban.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { userId } = req.query;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminUsers/'+userId+"/Unban", {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
},
|
||||
method: req.method
|
||||
});
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
return;
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
||||
|
19
pages/api/admin/users/[userId]/unsuspend.tsx
Normal file
19
pages/api/admin/users/[userId]/unsuspend.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { userId } = req.query;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminUsers/'+userId+"/Unsuspend", {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
},
|
||||
method: req.method
|
||||
});
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
return;
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
||||
|
16
pages/api/admin/users/count.tsx
Normal file
16
pages/api/admin/users/count.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/admin/AdminUsers/Count', {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
return;
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
16
pages/api/artist/artistAccessRequest.tsx
Normal file
16
pages/api/artist/artistAccessRequest.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
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/Artist', {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${accessToken}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
method: 'POST',
|
||||
body: req.body
|
||||
});
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
||||
|
@ -7,7 +7,9 @@ export default withApiAuthRequired(async function onboardUrl(req, res) {
|
||||
"Authorization": `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
|
||||
if(response.ok==false){
|
||||
res.status(200).json({})
|
||||
}
|
||||
let result = await response.json();
|
||||
res.status(200).json(result);
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function products(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/Requests/Artist/'+requestId+'/Accept', {
|
||||
|
@ -6,7 +6,7 @@ async function createBlobFromFile(path: string): Promise<Blob> {
|
||||
const file = await fs.readFile(path);
|
||||
return new Blob([file]);
|
||||
}
|
||||
export default withApiAuthRequired(async function products(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/Requests/Artist/'+requestId+'/Assets', {
|
||||
|
@ -3,7 +3,7 @@ import axios from 'axios';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export default withApiAuthRequired(async function references(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const assetId = req.query.assetId;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function products(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/Requests/Artist/'+requestId+'/Complete', {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function products(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/Requests/Artist/'+requestId+'/Deny', {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function requestDetails(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/Requests/Artist/'+requestId, {
|
||||
|
@ -3,7 +3,7 @@ import axios from 'axios';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export default withApiAuthRequired(async function references(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const referenceId = req.query.referenceId;
|
||||
|
@ -3,7 +3,7 @@ import { withApiAuthRequired } from "@auth0/nextjs-auth0";
|
||||
import { getAccessToken } from '@auth0/nextjs-auth0';
|
||||
|
||||
|
||||
export default withApiAuthRequired(async function me(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
if(req.method !== 'GET') {
|
||||
////console.log(req.body)
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function onboardUrl(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { completed, declined, accepted, paid, offset, pageSize } = req.body;
|
||||
const apiUrl = `${process.env.NEXT_PUBLIC_API_URL}/api/Requests/Customer/Count?completed=${completed}&declined=${declined}&accepted=${accepted}&paid=${paid}&offset=${offset}&pageSize=${pageSize}`;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function onboardUrl(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const { completed, declined, accepted, paid, offset, pageSize } = req.body;
|
||||
const apiUrl = `${process.env.NEXT_PUBLIC_API_URL}/api/Requests/Customer?completed=${completed}&declined=${declined}&accepted=${accepted}&paid=${paid}&offset=${offset}&pageSize=${pageSize}`;
|
||||
|
@ -6,7 +6,7 @@ async function createBlobFromFile(path: string): Promise<Blob> {
|
||||
const file = await fs.readFile(path);
|
||||
return new Blob([file]);
|
||||
}
|
||||
export default withApiAuthRequired(async function products(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/Requests/Customer/'+requestId+'/Assets', {
|
||||
|
@ -3,7 +3,7 @@ import axios from 'axios';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export default withApiAuthRequired(async function references(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const assetId = req.query.assetId;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function requestDetails(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/Requests/Customer/'+requestId, {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function products(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/Requests/Customer/'+requestId+'/Payment', {
|
||||
|
@ -6,7 +6,7 @@ async function createBlobFromFile(path: string): Promise<Blob> {
|
||||
const file = await fs.readFile(path);
|
||||
return new Blob([file]);
|
||||
}
|
||||
export default withApiAuthRequired(async function products(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/Requests/Customer/'+requestId+'/References', {
|
||||
|
@ -3,7 +3,7 @@ import axios from 'axios';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export default withApiAuthRequired(async function references(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const referenceId = req.query.referenceId;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { getAccessToken, withApiAuthRequired, getSession } from '@auth0/nextjs-auth0';
|
||||
|
||||
export default withApiAuthRequired(async function products(req, res) {
|
||||
export default withApiAuthRequired(async function handler(req, res) {
|
||||
const { accessToken } = await getAccessToken(req, res);
|
||||
const requestId = req.query.requestId;
|
||||
const response = await fetch(process.env.NEXT_PUBLIC_API_URL+'/api/Requests/Customer/'+requestId+'/Review', {
|
||||
|
@ -23,7 +23,7 @@ import { profile } from "console";
|
||||
import FileOpen from "@mui/icons-material/FileOpen";
|
||||
import Reviews from "../../components/dashboard/artist/reviews";
|
||||
|
||||
const Profile = () => {
|
||||
const ArtistBox = () => {
|
||||
|
||||
const [profileData, setArtistData] = useState(null);
|
||||
const [description, setDescription] = useState("");
|
||||
@ -252,6 +252,6 @@ const Profile = () => {
|
||||
};
|
||||
|
||||
// Protected route, checking user authentication client-side.(CSR)
|
||||
export default withPageAuthRequired(Profile);
|
||||
export default withPageAuthRequired(ArtistBox);
|
||||
|
||||
|
||||
|
@ -1,83 +0,0 @@
|
||||
// ** MUI Imports
|
||||
import Grid from '@mui/material/Grid'
|
||||
import Typography from '@mui/material/Typography'
|
||||
|
||||
// ** Demo Components Imports
|
||||
import CardUser from '../views/cards/CardUser'
|
||||
import CardImgTop from '../views/cards/CardImgTop'
|
||||
import CardMobile from '../views/cards/CardMobile'
|
||||
import CardSupport from '../views/cards/CardSupport'
|
||||
import CardTwitter from '../views/cards/CardTwitter'
|
||||
import CardFacebook from '../views/cards/CardFacebook'
|
||||
import CardLinkedIn from '../views/cards/CardLinkedIn'
|
||||
import CardAppleWatch from '../views/cards/CardAppleWatch'
|
||||
import CardMembership from '../views/cards/CardMembership'
|
||||
import CardInfluencer from '../views/cards/CardInfluencer'
|
||||
import CardNavigation from '../views/cards/CardNavigation'
|
||||
import CardWithCollapse from '../views/cards/CardWithCollapse'
|
||||
import CardVerticalRatings from '../views/cards/CardVerticalRatings'
|
||||
import CardNavigationCenter from '../views/cards/CardNavigationCenter'
|
||||
import CardHorizontalRatings from '../views/cards/CardHorizontalRatings'
|
||||
|
||||
const CardBasic = () => {
|
||||
return (
|
||||
<Grid container spacing={6}>
|
||||
<Grid item xs={12} sx={{ paddingBottom: 4 }}>
|
||||
<Typography variant='h5'>Basic Cards</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardImgTop />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardUser />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardWithCollapse />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<CardMobile />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<CardHorizontalRatings />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardAppleWatch />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={8}>
|
||||
<CardMembership />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardInfluencer />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardVerticalRatings />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardSupport />
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{ pb: 4, pt: theme => `${theme.spacing(17.5)} !important` }}>
|
||||
<Typography variant='h5'>Navigation Cards</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<CardNavigation />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<CardNavigationCenter />
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{ pb: 4, pt: theme => `${theme.spacing(17.5)} !important` }}>
|
||||
<Typography variant='h5'>Solid Cards</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardTwitter />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardFacebook />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<CardLinkedIn />
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
export default CardBasic
|
151
pages/dashboard/admin/artists.tsx
Normal file
151
pages/dashboard/admin/artists.tsx
Normal file
@ -0,0 +1,151 @@
|
||||
import * as React from 'react';
|
||||
import { DataGrid } from '@mui/x-data-grid';
|
||||
import { GridColDef } from '@mui/x-data-grid';
|
||||
import TextField from '@mui/material/TextField';
|
||||
import { Button, Stack, Typography } from '@mui/material';
|
||||
import CurrencyTextField from '@lupus-ai/mui-currency-textfield';
|
||||
import { DateField } from '@mui/x-date-pickers/DateField';
|
||||
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
||||
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
||||
import Chip from '@mui/material/Chip';
|
||||
import {Block, Check, Close, Download, OpenInFull, OpenInNew, Refresh, Star, Upload } from '@mui/icons-material';
|
||||
import PriceCheckIcon from '@mui/icons-material/PriceCheck';
|
||||
import AssignmentTurnedInIcon from '@mui/icons-material/AssignmentTurnedIn';
|
||||
import AssignmentLateIcon from '@mui/icons-material/AssignmentLate';
|
||||
import ShoppingCartCheckoutIcon from '@mui/icons-material/ShoppingCartCheckout';
|
||||
import { IconButton } from '@mui/material';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
import { Card, CardContent } from '@mui/material';
|
||||
import Rating from '@mui/material/Rating';
|
||||
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
import { DownloadBox, Magnify, StarOutline } from 'mdi-material-ui';
|
||||
import { Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, FormControl, InputLabel, Box } from '@mui/material';
|
||||
import { Grid } from '@mui/material';
|
||||
import { useRouter } from 'next/router';
|
||||
import { request } from 'http';
|
||||
import { useMediaQuery } from '@mui/material';
|
||||
|
||||
|
||||
export default function AdminArtists() {
|
||||
const isSmallScreen = useMediaQuery(theme => theme.breakpoints.down('sm')); // Check if the screen size is small
|
||||
const router = useRouter();
|
||||
let columns = [];
|
||||
if(isSmallScreen){
|
||||
columns = [
|
||||
{ field: 'id', headerName: '', flex: 0.05, sortable: false, filterable: false},
|
||||
];
|
||||
}
|
||||
else{
|
||||
columns = [
|
||||
{ field: 'id', headerName: '', flex: 0.05, sortable: false, filterable: false},
|
||||
{ field: 'displayName', headerName: 'User Name', flex: 0.15, sortable: false, filterable: false, valueGetter: (params) => {
|
||||
return params.row.user.displayName
|
||||
}},
|
||||
{ field: 'name', headerName: 'Artist Name', flex: 0.15, sortable: false, filterable: false, valueGetter: (params) => {
|
||||
return params.row.name
|
||||
}},
|
||||
{ field: 'email', headerName: 'Email', flex: 0.15, sortable: false, filterable: false, valueGetter: (params) => {
|
||||
return params.row.user.email
|
||||
}},
|
||||
{ field: 'numberOfRequests', headerName: '# of Requests', flex: 0.1, sortable: false, filterable: false},
|
||||
{ field: 'averageRating', headerName: 'Average Rating', flex: 0.1, sortable: false, filterable: false},
|
||||
{ field: 'amountMade', headerName: 'Amount Made', flex: 0.1, sortable: false, filterable: false},
|
||||
{ field: 'feesCollected', headerName: 'Fees Collected', flex: 0.1, sortable: false, filterable: false},
|
||||
{ field: 'status', headerName: 'Status', flex: 0.1, sortable: false, filterable: false, renderCell: (params) =>{
|
||||
if(params.row.user.banned){
|
||||
return <Chip icon={<Block />} label="Banned" variant="outlined" color="error" />
|
||||
}
|
||||
else if(params.row.suspended || params.row.user.suspended){
|
||||
return <Chip icon={<Block />} label="Suspended" variant="outlined" color="error" />
|
||||
}
|
||||
else{
|
||||
return <Chip icon={<Check />} label="Active" variant="outlined" color="success" />
|
||||
}
|
||||
}},
|
||||
{ field: 'actions', headerName: '', flex: 0.05, sortable: false, filterable: false, renderCell: (params) => {
|
||||
return <Tooltip title="View more information about this user."><IconButton color="info" onClick={() => router.push("/dashboard/admin/artists/"+params.row.id)}><OpenInNew /></IconButton></Tooltip>
|
||||
}}
|
||||
];
|
||||
}
|
||||
const [isLoading, setIsLoading] = React.useState(true);
|
||||
const [requestCount, setRequestCount] = React.useState(null);
|
||||
const [requestData, setRequestData] = React.useState({});
|
||||
const [paginationModel, setPaginationModel] = React.useState({
|
||||
page: 0,
|
||||
pageSize: 15,
|
||||
});
|
||||
|
||||
|
||||
const getRequests = async () => {
|
||||
setIsLoading(true);
|
||||
const response = await fetch('/api/admin/artists', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
completed: true, // Example query parameter
|
||||
declined: true, // Example query parameter
|
||||
accepted: true, // Example query parameter
|
||||
paid: true, // Example query parameter
|
||||
offset: paginationModel.page*paginationModel.pageSize, // Example query parameter
|
||||
pageSize: paginationModel.pageSize
|
||||
}),
|
||||
});
|
||||
const data = await response.json();
|
||||
setRequestData(data);
|
||||
setIsLoading(false);
|
||||
}
|
||||
const getRequestsCount = async () => {
|
||||
const response = await fetch('/api/admin/artists/count', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
completed: true, // Example query parameter
|
||||
declined: true, // Example query parameter
|
||||
accepted: true, // Example query parameter
|
||||
paid: true, // Example query parameter
|
||||
offset: paginationModel.page*paginationModel.pageSize, // Example query parameter
|
||||
pageSize: paginationModel.pageSize
|
||||
})
|
||||
});
|
||||
const data = await response.json();
|
||||
setRequestCount(data);
|
||||
setRowCountState((prevRowCountState) =>
|
||||
data !== undefined
|
||||
? data
|
||||
: prevRowCountState,
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
// Some API clients return undefined while loading
|
||||
// Following lines are here to prevent `rowCountState` from being undefined during the loading
|
||||
const [rowCountState, setRowCountState] = React.useState(0);
|
||||
React.useEffect(() => {
|
||||
getRequests();
|
||||
getRequestsCount();
|
||||
}, [requestCount, setRowCountState,paginationModel]);
|
||||
|
||||
return (
|
||||
|
||||
<div style={{ height: '100%', width: '100%' }}>
|
||||
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||
<DataGrid
|
||||
rows={requestData}
|
||||
columns={columns}
|
||||
rowCount={rowCountState}
|
||||
loading={isLoading}
|
||||
pageSizeOptions={[15]}
|
||||
paginationModel={paginationModel}
|
||||
paginationMode="server"
|
||||
onPaginationModelChange={setPaginationModel}
|
||||
/>
|
||||
</LocalizationProvider>
|
||||
</div>
|
||||
);
|
||||
}
|
104
pages/dashboard/admin/artists/[artistId].tsx
Normal file
104
pages/dashboard/admin/artists/[artistId].tsx
Normal file
@ -0,0 +1,104 @@
|
||||
import * as React from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { withPageAuthRequired } from '@auth0/nextjs-auth0/client'
|
||||
import { Alert, Card, CardContent, Grid, IconButton, TextField, Typography } from '@mui/material';
|
||||
import { ArrowBack, ArrowLeft, Block, Close } from '@mui/icons-material';
|
||||
import Button from '@mui/material/Button';
|
||||
import { OpenInNew } from 'mdi-material-ui';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
|
||||
const AdminArtist = () => {
|
||||
const router = useRouter();
|
||||
|
||||
|
||||
const [artist, setArtist] = useState(null);
|
||||
|
||||
const getData = async () => {
|
||||
if(router.query.artistId!=null){
|
||||
const response = await fetch("/api/admin/artists/"+router.query.artistId);
|
||||
const data = await response.json();
|
||||
setArtist(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
getData()
|
||||
}, [router.query.artistId]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="h5">Artist Information</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={6} sx={{textAlign:"right"}}>
|
||||
<Tooltip title="Ban this artist.">
|
||||
<IconButton color="error">
|
||||
<Block/>
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Suspend this artist.">
|
||||
<IconButton color="warning">
|
||||
<Close/>
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Go back a page.">
|
||||
<IconButton onClick={() => router.push("/dashboard/admin/artists")} color="primary">
|
||||
<ArrowBack/>
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12} md={5}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
Display Name: {artist?.user?.displayName}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
Email: {artist?.user?.email}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Button variant="contained" color="primary" fullWidth>Save Changes</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={7}>
|
||||
<TextField size="small" label="Admin Notes" multiline rows={4} fullWidth variant="outlined" value={artist?.userId} />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Alert severity={artist?.numberOfBans > 0 ? "error" : "success"}>{artist?.numberOfBans > 0 ? "This user has been banned "+artist?.numberOfBans+" times." : "This user has not been banned before."}</Alert>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Alert severity={artist?.numberOfSuspensions > 0 ? "error" : "success"}>{artist?.numberOfBans > 0 ? "This user has been suspended "+artist?.numberOfSuspensions+" times." : "This user has not been suspended before."}</Alert>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<Alert severity="success">This artist has made ${artist?.amountMade}, and we have made ${artist?.feesCollected} in fees.</Alert>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Alert severity={artist?.numberOfRequests > 0 ? "success" : "warning"}>This artist has accepted {artist?.numberOfRequests} requests.</Alert>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Alert severity={artist?.numberOfCompleted > 0 ? "success" : "warning"}>This artist has completed {artist?.numberOfCompleted} requests.</Alert>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
// Protected route, checking user authentication client-side.(CSR)
|
||||
export default withPageAuthRequired(AdminArtist);
|
||||
|
||||
|
@ -1,50 +1,206 @@
|
||||
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 * as React from 'react';
|
||||
import { DataGrid } from '@mui/x-data-grid';
|
||||
import { GridColDef } from '@mui/x-data-grid';
|
||||
import TextField from '@mui/material/TextField';
|
||||
import Button from '@mui/material/Button';
|
||||
import Switch from '@mui/material/Switch';
|
||||
import Divider from '@mui/material/Divider';
|
||||
import ArtistRequest from "../../../components/dashboard/admin/artistRequest";
|
||||
import { Button, Stack, Typography } from '@mui/material';
|
||||
import CurrencyTextField from '@lupus-ai/mui-currency-textfield';
|
||||
import { DateField } from '@mui/x-date-pickers/DateField';
|
||||
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
||||
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
||||
import Chip from '@mui/material/Chip';
|
||||
import {Block, Check, Close, Download, OpenInFull, OpenInNew, Person, Refresh, Star, Upload } from '@mui/icons-material';
|
||||
import PriceCheckIcon from '@mui/icons-material/PriceCheck';
|
||||
import AssignmentTurnedInIcon from '@mui/icons-material/AssignmentTurnedIn';
|
||||
import AssignmentLateIcon from '@mui/icons-material/AssignmentLate';
|
||||
import ShoppingCartCheckoutIcon from '@mui/icons-material/ShoppingCartCheckout';
|
||||
import { IconButton } from '@mui/material';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
import { Card, CardContent } from '@mui/material';
|
||||
import Rating from '@mui/material/Rating';
|
||||
|
||||
const ArtistRequests = () => {
|
||||
const {user, isLoading} = useUser();
|
||||
const [artistRequestData, setArtistRequestData] = useState(null);
|
||||
const getData = () => {
|
||||
fetch('/api/admin/requests').then(response => response.json().then(data => setArtistRequestData(data)))
|
||||
}
|
||||
useEffect(() => {
|
||||
getData()
|
||||
}, []);
|
||||
return (
|
||||
<Grid container spacing={2}>
|
||||
{(artistRequestData != null && Object.keys(artistRequestData).length>0) ? (
|
||||
(artistRequestData.map((request) => {
|
||||
|
||||
let formattedTime = "";
|
||||
if (artistRequestData) {
|
||||
const date = new Date(request["requestDate"]);
|
||||
formattedTime = date.toLocaleTimeString('en-US', {
|
||||
month: 'long',
|
||||
day: '2-digit',
|
||||
year: 'numeric',
|
||||
hour12: true,
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
}); // Example format
|
||||
import dayjs from 'dayjs';
|
||||
import { DownloadBox, Magnify, StarOutline } from 'mdi-material-ui';
|
||||
import { Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, FormControl, InputLabel, Box } from '@mui/material';
|
||||
import { Grid } from '@mui/material';
|
||||
import { useRouter } from 'next/router';
|
||||
import { request } from 'http';
|
||||
import { useMediaQuery } from '@mui/material';
|
||||
|
||||
|
||||
export default function AdminRequests() {
|
||||
const isSmallScreen = useMediaQuery(theme => theme.breakpoints.down('sm')); // Check if the screen size is small
|
||||
const router = useRouter();
|
||||
let columns = [];
|
||||
if(isSmallScreen){
|
||||
columns = [
|
||||
{ field: 'id', headerName: '', flex: 0.05, sortable: false, filterable: false},
|
||||
{ field: 'message', headerName: 'Message', flex: 0.2, sortable: false, filterable: false},
|
||||
{ field: 'actions', headerName: '', flex: 0.15, sortable: false, filterable: false, renderCell: (params) => {
|
||||
const handleAccept = async () => {
|
||||
var response = await fetch("/api/admin/requests/"+params.row.userId, {method:"PUT"})
|
||||
if(response.ok){
|
||||
var data = await response.json();
|
||||
router.reload();
|
||||
}
|
||||
else{
|
||||
alert("Failed to accept request.")
|
||||
}
|
||||
}
|
||||
const handleDeny = async () => {
|
||||
var response = await fetch("/api/admin/requests/"+params.row.userId, {method:"DELETE"})
|
||||
if(response.ok){
|
||||
var data = await response.json();
|
||||
router.reload();
|
||||
}
|
||||
else{
|
||||
alert("Failed to deny request.")
|
||||
}
|
||||
}
|
||||
if(params.row.accepted){
|
||||
return <>
|
||||
<Tooltip title="Revoke artist access"><IconButton color="error"><Block/></IconButton></Tooltip>
|
||||
<Tooltip title="View artist information"><IconButton onClick={() => router.push("/dashboard/admin/requests/"+params.row.id)} color="info"><Magnify/></IconButton></Tooltip>
|
||||
</>
|
||||
}
|
||||
else{
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="Accept this request and grant artist access."><IconButton onClick={handleAccept} color="success"><Check/></IconButton></Tooltip>
|
||||
<Tooltip title="Decline this request and refuse artist access."><IconButton onClick={handleDeny} color="error"><Close/></IconButton></Tooltip>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}}
|
||||
];
|
||||
}
|
||||
else{
|
||||
columns = [
|
||||
{ field: 'id', headerName: '', flex: 0.05, sortable: false, filterable: false},
|
||||
{ field: 'userId', headerName: 'User ID', flex: 0.25, sortable: false, filterable: false},
|
||||
{ field: 'message', headerName: 'Message', flex: 0.5, sortable: false, filterable: false},
|
||||
{ field: 'requestDate', headerName: 'Request Date', flex: 0.1, sortable: false, filterable: false, type: 'date', valueGetter: (params) => { return new Date(params.row.requestDate); }},
|
||||
{ field: 'accepted', headerName:'Accepted', flex: 0.15, sortable: false, filterable: false, renderCell: (params) => {
|
||||
return (params.row.accepted ? <Chip icon={<Check />} label="Accepted" variant="outlined" color="success" /> : <Chip icon={<Refresh />} label="Pending" variant="outlined" color="info" />)
|
||||
}},
|
||||
{ field: 'actions', headerName: '', flex: 0.15, sortable: false, filterable: false, renderCell: (params) => {
|
||||
const handleAccept = async () => {
|
||||
var response = await fetch("/api/admin/requests/"+params.row.userId, {method:"PUT"})
|
||||
if(response.ok){
|
||||
var data = await response.json();
|
||||
router.reload();
|
||||
}
|
||||
else{
|
||||
alert("Failed to accept request.")
|
||||
}
|
||||
}
|
||||
const handleDeny = async () => {
|
||||
var response = await fetch("/api/admin/requests/"+params.row.userId, {method:"DELETE"})
|
||||
if(response.ok){
|
||||
var data = await response.json();
|
||||
router.reload();
|
||||
}
|
||||
else{
|
||||
alert("Failed to deny request.")
|
||||
}
|
||||
}
|
||||
if(params.row.accepted){
|
||||
return <>
|
||||
<Tooltip title="View request information"><IconButton onClick={() => router.push("/dashboard/admin/requests/"+params.row.id)} color="info"><OpenInNew/></IconButton></Tooltip>
|
||||
<Tooltip title="View artist information"><IconButton onClick={() => router.push("/dashboard/admin/users/"+params.row.id)} color="info"><Person/></IconButton></Tooltip>
|
||||
</>
|
||||
}
|
||||
else{
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="View request information"><IconButton onClick={() => router.push("/dashboard/admin/requests/"+params.row.id)} color="info"><OpenInNew/></IconButton></Tooltip>
|
||||
<Tooltip title="Accept this request and grant artist access."><IconButton onClick={handleAccept} color="success"><Check/></IconButton></Tooltip>
|
||||
<Tooltip title="Decline this request and refuse artist access."><IconButton onClick={handleDeny} color="error"><Close/></IconButton></Tooltip>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}}
|
||||
];
|
||||
}
|
||||
const [isLoading, setIsLoading] = React.useState(true);
|
||||
const [requestCount, setRequestCount] = React.useState(null);
|
||||
const [requestData, setRequestData] = React.useState({});
|
||||
const [paginationModel, setPaginationModel] = React.useState({
|
||||
page: 0,
|
||||
pageSize: 15,
|
||||
});
|
||||
|
||||
|
||||
const getRequests = async () => {
|
||||
setIsLoading(true);
|
||||
const response = await fetch('/api/admin/requests', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
completed: true, // Example query parameter
|
||||
declined: true, // Example query parameter
|
||||
accepted: true, // Example query parameter
|
||||
paid: true, // Example query parameter
|
||||
offset: paginationModel.page*paginationModel.pageSize, // Example query parameter
|
||||
pageSize: paginationModel.pageSize
|
||||
}),
|
||||
});
|
||||
const data = await response.json();
|
||||
setRequestData(data);
|
||||
setIsLoading(false);
|
||||
}
|
||||
return (
|
||||
<ArtistRequest userid={request["userId"]} id={request["id"]} username={""} message={request["message"]} date={formattedTime} reload={getData} />
|
||||
)
|
||||
}
|
||||
))
|
||||
):(<Typography>No requests</Typography>)}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
const getRequestsCount = async () => {
|
||||
const response = await fetch('/api/admin/requests/count', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
completed: true, // Example query parameter
|
||||
declined: true, // Example query parameter
|
||||
accepted: true, // Example query parameter
|
||||
paid: true, // Example query parameter
|
||||
offset: paginationModel.page*paginationModel.pageSize, // Example query parameter
|
||||
pageSize: paginationModel.pageSize
|
||||
})
|
||||
});
|
||||
const data = await response.json();
|
||||
setRequestCount(data);
|
||||
setRowCountState((prevRowCountState) =>
|
||||
data !== undefined
|
||||
? data
|
||||
: prevRowCountState,
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
// Protected route, checking user authentication client-side.(CSR)
|
||||
export default withPageAuthRequired(ArtistRequests);
|
||||
// Some API clients return undefined while loading
|
||||
// Following lines are here to prevent `rowCountState` from being undefined during the loading
|
||||
const [rowCountState, setRowCountState] = React.useState(0);
|
||||
React.useEffect(() => {
|
||||
getRequests();
|
||||
getRequestsCount();
|
||||
}, [requestCount, setRowCountState,paginationModel]);
|
||||
|
||||
return (
|
||||
|
||||
<div style={{ height: '100%', width: '100%' }}>
|
||||
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||
<DataGrid
|
||||
rows={requestData}
|
||||
columns={columns}
|
||||
rowCount={rowCountState}
|
||||
loading={isLoading}
|
||||
pageSizeOptions={[15]}
|
||||
paginationModel={paginationModel}
|
||||
paginationMode="server"
|
||||
onPaginationModelChange={setPaginationModel}
|
||||
/>
|
||||
</LocalizationProvider>
|
||||
</div>
|
||||
);
|
||||
}
|
124
pages/dashboard/admin/requests/[requestId].tsx
Normal file
124
pages/dashboard/admin/requests/[requestId].tsx
Normal file
@ -0,0 +1,124 @@
|
||||
import * as React from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { withPageAuthRequired } from '@auth0/nextjs-auth0/client'
|
||||
import { Alert, Card, CardContent, Grid, IconButton, TextField, Typography } from '@mui/material';
|
||||
import Button from '@mui/material/Button';
|
||||
import { OpenInNew } from 'mdi-material-ui';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
import { ArrowBack } from '@mui/icons-material';
|
||||
|
||||
|
||||
const AdminRequest = () => {
|
||||
const router = useRouter();
|
||||
|
||||
const [request, setRequest] = useState(null);
|
||||
|
||||
|
||||
const getData = async () => {
|
||||
if(router.query.requestId!=null){
|
||||
const response = await fetch("/api/admin/requests/"+router.query.requestId);
|
||||
const data = await response.json();
|
||||
setRequest(data);
|
||||
}
|
||||
}
|
||||
|
||||
const handleAccept = async () => {
|
||||
var response = await fetch("/api/admin/requests/"+router.query.requestId, {method:"PUT"})
|
||||
if(response.ok){
|
||||
var data = await response.json();
|
||||
router.reload();
|
||||
}
|
||||
else{
|
||||
alert("Failed to accept request.")
|
||||
}
|
||||
}
|
||||
const handleDeny = async () => {
|
||||
var response = await fetch("/api/admin/requests/"+router.query.requestId, {method:"DELETE"})
|
||||
if(response.ok){
|
||||
var data = await response.json();
|
||||
router.reload();
|
||||
}
|
||||
else{
|
||||
alert("Failed to deny request.")
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getData()
|
||||
}, [router.query.requestId]);
|
||||
|
||||
let formattedTime = ""
|
||||
const date = new Date(request?.requestDate);
|
||||
formattedTime = date.toLocaleTimeString('en-US', { month: 'long', day: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); // Example format
|
||||
return (
|
||||
<>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Grid container>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="h5">{router.query.requestId} - Artist Access Request</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={6} sx={{textAlign:"right"}}>
|
||||
<Tooltip title="Go back a page.">
|
||||
<IconButton onClick={() => router.push("/dashboard/admin/requests")} color="primary">
|
||||
<ArrowBack/>
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<Alert severity="info">Submitted on {formattedTime}</Alert>
|
||||
</Grid>
|
||||
{request?.accepted ? (
|
||||
<Grid item xs={12}>
|
||||
<Alert severity="success">This artist access request has been accepted.</Alert>
|
||||
</Grid>
|
||||
):(
|
||||
<Grid item xs={12}>
|
||||
<Alert severity="warning">Pending review from platform administrator.</Alert>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item xs={12}>
|
||||
<TextField
|
||||
id="outlined-multiline-static"
|
||||
label="Message"
|
||||
multiline
|
||||
rows={4}
|
||||
fullWidth
|
||||
value={request?.message}
|
||||
disabled>
|
||||
{request?.message}
|
||||
</TextField>
|
||||
</Grid>
|
||||
{request?.accepted ? (
|
||||
<Grid item xs={12} md={12}>
|
||||
<Button fullWidth variant="contained" onClick={handleAccept} color="error">Revoke Artist Access</Button>
|
||||
</Grid>
|
||||
):(
|
||||
<>
|
||||
<Grid item xs={12} md={6}>
|
||||
<Button fullWidth variant="contained" onClick={handleAccept} color="primary">Accept</Button>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<Button fullWidth variant="contained" onClick={handleDeny} color="secondary">Reject</Button>
|
||||
</Grid>
|
||||
</>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
// Protected route, checking user authentication client-side.(CSR)
|
||||
export default withPageAuthRequired(AdminRequest);
|
||||
|
||||
|
147
pages/dashboard/admin/users.tsx
Normal file
147
pages/dashboard/admin/users.tsx
Normal file
@ -0,0 +1,147 @@
|
||||
import * as React from 'react';
|
||||
import { DataGrid } from '@mui/x-data-grid';
|
||||
import { GridColDef } from '@mui/x-data-grid';
|
||||
import TextField from '@mui/material/TextField';
|
||||
import { Button, Stack, Typography } from '@mui/material';
|
||||
import CurrencyTextField from '@lupus-ai/mui-currency-textfield';
|
||||
import { DateField } from '@mui/x-date-pickers/DateField';
|
||||
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
||||
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
||||
import Chip from '@mui/material/Chip';
|
||||
import {Block, Check, Close, Download, OpenInFull, OpenInNew, Refresh, Star, Upload } from '@mui/icons-material';
|
||||
import PriceCheckIcon from '@mui/icons-material/PriceCheck';
|
||||
import AssignmentTurnedInIcon from '@mui/icons-material/AssignmentTurnedIn';
|
||||
import AssignmentLateIcon from '@mui/icons-material/AssignmentLate';
|
||||
import ShoppingCartCheckoutIcon from '@mui/icons-material/ShoppingCartCheckout';
|
||||
import { IconButton } from '@mui/material';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
import { Card, CardContent } from '@mui/material';
|
||||
import Rating from '@mui/material/Rating';
|
||||
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
import { DownloadBox, Magnify, StarOutline } from 'mdi-material-ui';
|
||||
import { Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, FormControl, InputLabel, Box } from '@mui/material';
|
||||
import { Grid } from '@mui/material';
|
||||
import { useRouter } from 'next/router';
|
||||
import { request } from 'http';
|
||||
import { useMediaQuery } from '@mui/material';
|
||||
|
||||
|
||||
export default function AdminUsers() {
|
||||
const isSmallScreen = useMediaQuery(theme => theme.breakpoints.down('sm')); // Check if the screen size is small
|
||||
const router = useRouter();
|
||||
let columns = [];
|
||||
if(isSmallScreen){
|
||||
columns = [
|
||||
{ field: 'id', headerName: 'User ID', flex: 0.95, sortable: false, filterable: false},
|
||||
{ field: "actions", headerName: "Actions", flex: 0.05, sortable: false, filterable: false, renderCell: (params) => {
|
||||
return <Tooltip title="View more information about this user."><IconButton color="info" onClick={() => router.push("/dashboard/admin/users/"+params.row.id)}><OpenInNew /></IconButton></Tooltip>
|
||||
}}
|
||||
];
|
||||
}
|
||||
else{
|
||||
columns = [
|
||||
{ field: 'id', headerName: 'User ID', flex: 0.2, sortable: false, filterable: false},
|
||||
{ field: 'displayName', headerName: 'Display Name', flex: 0.15, sortable: false, filterable: false},
|
||||
{ field: 'email', headerName: 'Email', flex: 0.2, sortable: false, filterable: false},
|
||||
{ field: "numberOfRequests", headerName: "# of Requests", flex: 0.1, sortable: false, filterable: false},
|
||||
{ field: "numberOfReviews", headerName: "# of Reviews", flex: 0.1, sortable: false, filterable: false},
|
||||
{ field: "amountSpent", headerName: "Amount Spent", flex: 0.1, sortable: false, filterable: false},
|
||||
{ field: 'status', headerName: 'Status', flex: 0.1, sortable: false, filterable: false, renderCell: (params) =>{
|
||||
if(params.row.banned){
|
||||
return <Chip icon={<Block />} label="Banned" variant="outlined" color="error" />
|
||||
}
|
||||
else if(params.row.suspended){
|
||||
return <Chip icon={<Block />} label="Suspended" variant="outlined" color="error" />
|
||||
}
|
||||
else{
|
||||
return <Chip icon={<Check />} label="Active" variant="outlined" color="success" />
|
||||
}
|
||||
}},
|
||||
{ field: "actions", headerName: "", flex: 0.05, sortable: false, filterable: false, renderCell: (params) => {
|
||||
return <Tooltip title="View more information about this user."><IconButton color="info" onClick={() => router.push("/dashboard/admin/users/"+params.row.id)}><OpenInNew /></IconButton></Tooltip>
|
||||
}}
|
||||
];
|
||||
}
|
||||
const [isLoading, setIsLoading] = React.useState(true);
|
||||
const [requestCount, setRequestCount] = React.useState(null);
|
||||
const [requestData, setRequestData] = React.useState({});
|
||||
const [paginationModel, setPaginationModel] = React.useState({
|
||||
page: 0,
|
||||
pageSize: 15,
|
||||
});
|
||||
|
||||
|
||||
const getRequests = async () => {
|
||||
setIsLoading(true);
|
||||
const response = await fetch('/api/admin/users', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
completed: true, // Example query parameter
|
||||
declined: true, // Example query parameter
|
||||
accepted: true, // Example query parameter
|
||||
paid: true, // Example query parameter
|
||||
offset: paginationModel.page*paginationModel.pageSize, // Example query parameter
|
||||
pageSize: paginationModel.pageSize
|
||||
}),
|
||||
});
|
||||
const data = await response.json();
|
||||
setRequestData(data);
|
||||
setIsLoading(false);
|
||||
}
|
||||
const getRequestsCount = async () => {
|
||||
const response = await fetch('/api/admin/users/count', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
completed: true, // Example query parameter
|
||||
declined: true, // Example query parameter
|
||||
accepted: true, // Example query parameter
|
||||
paid: true, // Example query parameter
|
||||
offset: paginationModel.page*paginationModel.pageSize, // Example query parameter
|
||||
pageSize: paginationModel.pageSize
|
||||
})
|
||||
});
|
||||
const data = await response.json();
|
||||
setRequestCount(data);
|
||||
setRowCountState((prevRowCountState) =>
|
||||
data !== undefined
|
||||
? data
|
||||
: prevRowCountState,
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
// Some API clients return undefined while loading
|
||||
// Following lines are here to prevent `rowCountState` from being undefined during the loading
|
||||
const [rowCountState, setRowCountState] = React.useState(0);
|
||||
React.useEffect(() => {
|
||||
getRequests();
|
||||
getRequestsCount();
|
||||
}, [requestCount, setRowCountState,paginationModel]);
|
||||
|
||||
return (
|
||||
|
||||
<div style={{ height: '100%', width: '100%' }}>
|
||||
<Button target="_blank" href="https://manage.auth0.com/dashboard">Open Auth0 Dashboard</Button>
|
||||
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||
<DataGrid
|
||||
rows={requestData}
|
||||
columns={columns}
|
||||
rowCount={rowCountState}
|
||||
loading={isLoading}
|
||||
pageSizeOptions={[15]}
|
||||
paginationModel={paginationModel}
|
||||
paginationMode="server"
|
||||
onPaginationModelChange={setPaginationModel}
|
||||
/>
|
||||
</LocalizationProvider>
|
||||
</div>
|
||||
);
|
||||
}
|
104
pages/dashboard/admin/users/[userId].tsx
Normal file
104
pages/dashboard/admin/users/[userId].tsx
Normal file
@ -0,0 +1,104 @@
|
||||
import * as React from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { withPageAuthRequired } from '@auth0/nextjs-auth0/client'
|
||||
import { Alert, Card, CardContent, Grid, IconButton, TextField, Typography } from '@mui/material';
|
||||
import { ArrowBack, ArrowLeft, Block, Close } from '@mui/icons-material';
|
||||
import Button from '@mui/material/Button';
|
||||
import { OpenInNew } from 'mdi-material-ui';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
|
||||
const AdminUser = () => {
|
||||
const router = useRouter();
|
||||
|
||||
|
||||
const [user, setUser] = useState(null);
|
||||
|
||||
const getData = async () => {
|
||||
if(router.query.userId!=null){
|
||||
const response = await fetch("/api/admin/users/"+router.query.userId);
|
||||
const data = await response.json();
|
||||
setUser(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
getData()
|
||||
}, [router.query.userId]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="h5">User Information</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={6} sx={{textAlign:"right"}}>
|
||||
<Tooltip title="Ban this user.">
|
||||
<IconButton color="error">
|
||||
<Block/>
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Suspend this user.">
|
||||
<IconButton color="warning">
|
||||
<Close/>
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Go back a page.">
|
||||
<IconButton onClick={() => router.push("/dashboard/admin/users")} color="primary">
|
||||
<ArrowBack/>
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12} md={5}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
Display Name: {user?.displayName}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
Email: {user?.email}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Button variant="contained" color="primary" fullWidth>Save Changes</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={7}>
|
||||
<TextField size="small" label="Admin Notes" multiline rows={4} fullWidth variant="outlined" value={user?.userId} />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Alert severity={user?.numberOfBans > 0 ? "error" : "success"}>{user?.numberOfBans > 0 ? "This user has been banned "+user?.numberOfBans+" times." : "This user has not been banned before."}</Alert>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Alert severity={user?.numberOfSuspensions > 0 ? "error" : "success"}>{user?.numberOfBans > 0 ? "This user has been suspended "+user?.numberOfSuspensions+" times." : "This user has not been suspended before."}</Alert>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<Alert severity={user?.numberOfRequests > 0 ? "success" : "warning"}>This user has opened {user?.numberOfRequests} requests.</Alert>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Alert severity={user?.amountSpent > 0 ? "success" : "warning"}>This user has paid {user?.amountSpent} for {user?.numberOfPaid} requests.</Alert>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Alert severity={user?.numberOfReviews > 0 ? "success" : "warning"}>This user has left {user?.numberOfReviews} reviews on completed requests.</Alert>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
// Protected route, checking user authentication client-side.(CSR)
|
||||
export default withPageAuthRequired(AdminUser);
|
||||
|
||||
|
@ -21,130 +21,239 @@ import AssignmentTurnedInIcon from '@mui/icons-material/AssignmentTurnedIn';
|
||||
import AssignmentLateIcon from '@mui/icons-material/AssignmentLate';
|
||||
import { Card, CardHeader } from '@mui/material';
|
||||
import { Dialog, DialogActions, DialogContent, DialogTitle, Grid, Stack } from '@mui/material';
|
||||
import RequestReferences from '../../../components/requestReferences';
|
||||
|
||||
import { useMediaQuery } from '@mui/material';
|
||||
export default function ServerPaginationGrid() {
|
||||
const isSmallScreen = useMediaQuery(theme => theme.breakpoints.down('sm')); // Check if the screen size is small
|
||||
|
||||
const router = useRouter();
|
||||
const columns = [
|
||||
{ field: 'id', headerName: 'ID', flex: 0.1},
|
||||
{ field: 'status', headerName: 'Status', flex: 0.15,
|
||||
renderCell: (params) => {
|
||||
if(params.row.completed){
|
||||
return <Chip icon={<Check />} label="Completed" variant="outlined" color="success" />
|
||||
let columns = []
|
||||
if(isSmallScreen){
|
||||
columns = [
|
||||
{ field: 'id', headerName: 'ID', flex: 0.1, filterable: false, sortable: false},
|
||||
{ field: 'status', headerName: 'Status', flex: 0.15, filterable: false, sortable: false,
|
||||
renderCell: (params) => {
|
||||
if(params.row.completed){
|
||||
return <Check color="success" />
|
||||
}
|
||||
else if(params.row.paid){
|
||||
return <PriceCheckIcon color="success" />
|
||||
}
|
||||
else if(params.row.accepted && params.row.paid==false){
|
||||
return <PriceCheckIcon color="warning" />
|
||||
}
|
||||
else if(params.row.accepted && params.row.paid){
|
||||
return <AssignmentTurnedInIcon color="info" />
|
||||
}
|
||||
else if(params.row.declined){
|
||||
return <AssignmentLateIcon color="error" />
|
||||
}
|
||||
else{
|
||||
return <Refresh color="secondary" />
|
||||
}
|
||||
}
|
||||
else if(params.row.paid){
|
||||
return <Chip icon={<PriceCheckIcon />} label="Paid" variant="outlined" color="success" />
|
||||
}
|
||||
else if(params.row.accepted && params.row.paid==false){
|
||||
return <Chip icon={<PriceCheckIcon />} label="Pending Payment" variant="outlined" color="warning" />
|
||||
}
|
||||
else if(params.row.accepted && params.row.paid){
|
||||
return <Chip icon={<AssignmentTurnedInIcon />} label="Accepted" variant="outlined" color="info" />
|
||||
}
|
||||
else if(params.row.declined){
|
||||
return <Chip icon={<AssignmentLateIcon />} label="Declined" variant="outlined" color="error" />
|
||||
}
|
||||
else{
|
||||
return <Chip icon={<Refresh />} label="Pending" variant="outlined" color="secondary" />
|
||||
}
|
||||
}
|
||||
},
|
||||
{ field: 'message', headerName: 'Message', flex: 0.5,
|
||||
renderCell: (params) => {
|
||||
return <TextField size="small" fullWidth value={params.row.message} disabled />;
|
||||
},
|
||||
{ field: 'amount', headerName: 'Amount', flex: 0.15, filterable: false, sortable: false, renderCell: (params) => {
|
||||
return <CurrencyTextField size="small" fullWidth value={params.row.amount} currencySymbol="$" disabled />;
|
||||
}},
|
||||
{ field: 'amount', headerName: 'Amount', flex: 0.1, renderCell: (params) => {
|
||||
return <CurrencyTextField size="small" fullWidth value={params.row.amount} currencySymbol="$" disabled />;
|
||||
}},
|
||||
{ field: 'requestDate', headerName: 'Request Date', flex:0.15,
|
||||
renderCell: (params) =>{
|
||||
|
||||
let formattedTime = ""
|
||||
const date = new Date(params.row.requestDate);
|
||||
formattedTime = date.toLocaleTimeString('en-US', { month: 'long', day: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); // Example format
|
||||
return <DateField
|
||||
size='small'
|
||||
disabled
|
||||
defaultValue={dayjs(params.row.requestDate)}
|
||||
format="LL"
|
||||
/>
|
||||
} },
|
||||
{ field: 'action', headerName: '', flex:0.15,
|
||||
{ field: 'action', headerName: '', flex:0.1, filterable: false, sortable: false,
|
||||
renderCell: (params) =>{
|
||||
|
||||
const acceptRequest = async () => {
|
||||
let response = await fetch('/api/artist/requests/'+params.row["id"]+"/accept", { method: 'PUT' })
|
||||
if(response.status === 200){
|
||||
router.push("/dashboard/artist/requests/"+params.row["id"])
|
||||
}
|
||||
else{
|
||||
alert("Error accepting request.")
|
||||
}
|
||||
}
|
||||
|
||||
const viewRequest = async () => {
|
||||
|
||||
}
|
||||
|
||||
const denyRequest = async () => {
|
||||
let response = await fetch('/api/artist/requests/'+params.row["id"]+"/deny", { method: 'PUT' })
|
||||
if(response.status === 200){
|
||||
router.push("/dashboard/artist/requests/"+params.row["id"])
|
||||
}
|
||||
else{
|
||||
alert("Error accepting request.")
|
||||
}
|
||||
}
|
||||
|
||||
const completeRequest = async () => {
|
||||
let response = await fetch('/api/artist/requests/'+params.row["id"]+"/complete", { method: 'PUT' })
|
||||
if(response.status === 200){
|
||||
router.push("/dashboard/artist/requests/"+params.row["id"])
|
||||
}
|
||||
else{
|
||||
alert("Error accepting request.")
|
||||
}
|
||||
}
|
||||
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
const handleClickOpen = () => {
|
||||
setOpen(true);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
let formattedTime = ""
|
||||
const date = new Date(params.row.requestDate);
|
||||
formattedTime = date.toLocaleTimeString('en-US', { month: 'long', day: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); // Example format
|
||||
|
||||
return (<>
|
||||
<Tooltip arrow title="View more details."><IconButton onClick={() => { router.push("/dashboard/artist/requests/"+params.row["id"])}} aria-label="accept" color="primary" ><OpenInNew/></IconButton></Tooltip>
|
||||
{((params.row.accepted==false && params.row.declined==false && params.row.completed==false) ? (
|
||||
<>
|
||||
<Tooltip arrow title="Accept this request.">
|
||||
<IconButton onClick={acceptRequest} aria-label="accept" color="success"><Check/></IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip arrow title="Deny this request.">
|
||||
<IconButton onClick={denyRequest} aria-label="deny" sx={{marginLeft:"2px"}} color="error"><Close/></IconButton>
|
||||
</Tooltip>
|
||||
</>
|
||||
): null
|
||||
)}
|
||||
{((params.row.accepted==true && params.row.declined==false && params.row.completed==false && params.row.paid==true) ? (
|
||||
<>
|
||||
<Tooltip arrow title="Complete this request.">
|
||||
<IconButton onClick={completeRequest} aria-label="complete" color="success"><ClipboardCheck/></IconButton>
|
||||
</Tooltip>
|
||||
</>
|
||||
): null
|
||||
)}
|
||||
</>
|
||||
)
|
||||
} }
|
||||
];
|
||||
}
|
||||
else{
|
||||
columns = [
|
||||
{ field: 'id', headerName: 'ID', flex: 0.1, filterable: false, sortable: false},
|
||||
{ field: 'status', headerName: 'Status', flex: 0.15, filterable: false, sortable: false, filterable: false,
|
||||
renderCell: (params) => {
|
||||
if(params.row.completed){
|
||||
return <Chip icon={<Check />} label="Completed" variant="outlined" color="success" />
|
||||
}
|
||||
else if(params.row.paid){
|
||||
return <Chip icon={<PriceCheckIcon />} label="Paid" variant="outlined" color="success" />
|
||||
}
|
||||
else if(params.row.accepted && params.row.paid==false){
|
||||
return <Chip icon={<PriceCheckIcon />} label="Pending Payment" variant="outlined" color="warning" />
|
||||
}
|
||||
else if(params.row.accepted && params.row.paid){
|
||||
return <Chip icon={<AssignmentTurnedInIcon />} label="Accepted" variant="outlined" color="info" />
|
||||
}
|
||||
else if(params.row.declined){
|
||||
return <Chip icon={<AssignmentLateIcon />} label="Declined" variant="outlined" color="error" />
|
||||
}
|
||||
else{
|
||||
return <Chip icon={<Refresh />} label="Pending" variant="outlined" color="secondary" />
|
||||
}
|
||||
}
|
||||
},
|
||||
{ field: 'message', headerName: 'Message', flex: 0.5, filterable: false, sortable: false,
|
||||
renderCell: (params) => {
|
||||
return <TextField size="small" fullWidth value={params.row.message} disabled />;
|
||||
}},
|
||||
{ field: 'amount', headerName: 'Amount', flex: 0.1, filterable: false, sortable: false, renderCell: (params) => {
|
||||
return <CurrencyTextField size="small" fullWidth value={params.row.amount} currencySymbol="$" disabled />;
|
||||
}},
|
||||
{ field: 'requestDate', headerName: 'Request Date', flex:0.15, filterable: false, sortable: false,
|
||||
renderCell: (params) =>{
|
||||
|
||||
const acceptRequest = async () => {
|
||||
let response = await fetch('/api/artist/requests/'+params.row["id"]+"/accept", { method: 'PUT' })
|
||||
if(response.status === 200){
|
||||
router.push("/dashboard/artist/requests/"+params.row["id"])
|
||||
}
|
||||
else{
|
||||
alert("Error accepting request.")
|
||||
}
|
||||
}
|
||||
|
||||
const viewRequest = async () => {
|
||||
|
||||
}
|
||||
|
||||
const denyRequest = async () => {
|
||||
let response = await fetch('/api/artist/requests/'+params.row["id"]+"/deny", { method: 'PUT' })
|
||||
if(response.status === 200){
|
||||
router.push("/dashboard/artist/requests/"+params.row["id"])
|
||||
}
|
||||
else{
|
||||
alert("Error accepting request.")
|
||||
}
|
||||
}
|
||||
|
||||
const completeRequest = async () => {
|
||||
let response = await fetch('/api/artist/requests/'+params.row["id"]+"/complete", { method: 'PUT' })
|
||||
if(response.status === 200){
|
||||
router.push("/dashboard/artist/requests/"+params.row["id"])
|
||||
}
|
||||
else{
|
||||
alert("Error accepting request.")
|
||||
}
|
||||
}
|
||||
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
const handleClickOpen = () => {
|
||||
setOpen(true);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
|
||||
let formattedTime = ""
|
||||
const date = new Date(params.row.requestDate);
|
||||
formattedTime = date.toLocaleTimeString('en-US', { month: 'long', day: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); // Example format
|
||||
|
||||
return (<>
|
||||
<Tooltip arrow title="View more details."><IconButton onClick={() => { router.push("/dashboard/artist/requests/"+params.row["id"])}} aria-label="accept" color="primary" ><OpenInNew/></IconButton></Tooltip>
|
||||
{((params.row.accepted==false && params.row.declined==false && params.row.completed==false) ? (
|
||||
<>
|
||||
<Tooltip arrow title="Accept this request.">
|
||||
<IconButton onClick={acceptRequest} aria-label="accept" color="success"><Check/></IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip arrow title="Deny this request.">
|
||||
<IconButton onClick={denyRequest} aria-label="deny" sx={{marginLeft:"2px"}} color="error"><Close/></IconButton>
|
||||
return <DateField
|
||||
size='small'
|
||||
disabled
|
||||
defaultValue={dayjs(params.row.requestDate)}
|
||||
format="LL"
|
||||
/>
|
||||
} },
|
||||
{ field: 'action', headerName: '', flex:0.15, filterable: false, sortable: false,
|
||||
renderCell: (params) =>{
|
||||
|
||||
const acceptRequest = async () => {
|
||||
let response = await fetch('/api/artist/requests/'+params.row["id"]+"/accept", { method: 'PUT' })
|
||||
if(response.status === 200){
|
||||
router.push("/dashboard/artist/requests/"+params.row["id"])
|
||||
}
|
||||
else{
|
||||
alert("Error accepting request.")
|
||||
}
|
||||
}
|
||||
|
||||
const viewRequest = async () => {
|
||||
|
||||
}
|
||||
|
||||
const denyRequest = async () => {
|
||||
let response = await fetch('/api/artist/requests/'+params.row["id"]+"/deny", { method: 'PUT' })
|
||||
if(response.status === 200){
|
||||
router.push("/dashboard/artist/requests/"+params.row["id"])
|
||||
}
|
||||
else{
|
||||
alert("Error accepting request.")
|
||||
}
|
||||
}
|
||||
|
||||
const completeRequest = async () => {
|
||||
let response = await fetch('/api/artist/requests/'+params.row["id"]+"/complete", { method: 'PUT' })
|
||||
if(response.status === 200){
|
||||
router.push("/dashboard/artist/requests/"+params.row["id"])
|
||||
}
|
||||
else{
|
||||
alert("Error accepting request.")
|
||||
}
|
||||
}
|
||||
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
const handleClickOpen = () => {
|
||||
setOpen(true);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
let formattedTime = ""
|
||||
const date = new Date(params.row.requestDate);
|
||||
formattedTime = date.toLocaleTimeString('en-US', { month: 'long', day: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); // Example format
|
||||
|
||||
return (<>
|
||||
<Tooltip arrow title="View more details."><IconButton onClick={() => { router.push("/dashboard/artist/requests/"+params.row["id"])}} aria-label="accept" color="primary" ><OpenInNew/></IconButton></Tooltip>
|
||||
{((params.row.accepted==false && params.row.declined==false && params.row.completed==false) ? (
|
||||
<>
|
||||
<Tooltip arrow title="Accept this request.">
|
||||
<IconButton onClick={acceptRequest} aria-label="accept" color="success"><Check/></IconButton>
|
||||
</Tooltip>
|
||||
</>
|
||||
): null
|
||||
)}
|
||||
{((params.row.accepted==true && params.row.declined==false && params.row.completed==false && params.row.paid==true) ? (
|
||||
<>
|
||||
<Tooltip arrow title="Complete this request.">
|
||||
<IconButton onClick={completeRequest} aria-label="complete" color="success"><ClipboardCheck/></IconButton>
|
||||
</Tooltip>
|
||||
</>
|
||||
): null
|
||||
)}
|
||||
</>
|
||||
)
|
||||
} }
|
||||
];
|
||||
<Tooltip arrow title="Deny this request.">
|
||||
<IconButton onClick={denyRequest} aria-label="deny" sx={{marginLeft:"2px"}} color="error"><Close/></IconButton>
|
||||
</Tooltip>
|
||||
</>
|
||||
): null
|
||||
)}
|
||||
{((params.row.accepted==true && params.row.declined==false && params.row.completed==false && params.row.paid==true) ? (
|
||||
<>
|
||||
<Tooltip arrow title="Complete this request.">
|
||||
<IconButton onClick={completeRequest} aria-label="complete" color="success"><ClipboardCheck/></IconButton>
|
||||
</Tooltip>
|
||||
</>
|
||||
): null
|
||||
)}
|
||||
</>
|
||||
)
|
||||
} }
|
||||
];
|
||||
}
|
||||
const [isLoading, setIsLoading] = React.useState(true);
|
||||
const [requestCount, setRequestCount] = React.useState(null);
|
||||
const [requestData, setRequestData] = React.useState({});
|
||||
|
@ -293,11 +293,12 @@ const ArtistRequestDetails = () => {
|
||||
)
|
||||
:(
|
||||
<>
|
||||
<Box sx={{paddingTop:"20%", textAlign:"center"}}>
|
||||
<Typography variant="h6" component="h6" gutterBottom>
|
||||
Loading...
|
||||
</Typography>
|
||||
<Box sx={{paddingTop:"20%"}}></Box>
|
||||
<CircularProgress/>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
@ -25,78 +25,138 @@ import { Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, F
|
||||
import { Grid } from '@mui/material';
|
||||
import { useRouter } from 'next/router';
|
||||
import { request } from 'http';
|
||||
import { useMediaQuery } from '@mui/material';
|
||||
|
||||
|
||||
export default function ServerPaginationGrid() {
|
||||
const isSmallScreen = useMediaQuery(theme => theme.breakpoints.down('sm')); // Check if the screen size is small
|
||||
const router = useRouter();
|
||||
const columns = [
|
||||
{ field: 'id', headerName: 'ID', flex: 0.1},
|
||||
{ field: 'status', headerName: 'Status', flex: 0.15,
|
||||
renderCell: (params) => {
|
||||
if(params.row.completed){
|
||||
return <Chip icon={<Check />} label="Completed" variant="outlined" color="success" />
|
||||
}
|
||||
else if(params.row.paid){
|
||||
return <Chip icon={<PriceCheckIcon />} label="Paid" variant="outlined" color="success" />
|
||||
}
|
||||
else if(params.row.accepted && params.row.paid==false){
|
||||
return <Chip icon={<PriceCheckIcon />} label="Pending Payment" variant="outlined" color="warning" />
|
||||
}
|
||||
else if(params.row.accepted && params.row.paid){
|
||||
return <Chip icon={<AssignmentTurnedInIcon />} label="Accepted" variant="outlined" color="info" />
|
||||
}
|
||||
else if(params.row.declined){
|
||||
return <Chip icon={<AssignmentLateIcon />} label="Declined" variant="outlined" color="error" />
|
||||
}
|
||||
else{
|
||||
return <Chip icon={<Refresh />} label="Pending" variant="outlined" color="secondary" />
|
||||
}
|
||||
}
|
||||
},
|
||||
{ field: 'message', headerName: 'Message', flex: 0.5,
|
||||
renderCell: (params) => {
|
||||
return <TextField size="small" fullWidth value={params.row.message} disabled />;
|
||||
}},
|
||||
{ field: 'amount', headerName: 'Amount', flex: 0.1, renderCell: (params) => {
|
||||
return <CurrencyTextField size="small" fullWidth value={params.row.amount} currencySymbol="$" disabled />;
|
||||
}},
|
||||
{ field: 'requestDate', headerName: 'Request Date', flex:0.15,
|
||||
renderCell: (params) =>{
|
||||
let columns = [];
|
||||
if(isSmallScreen){
|
||||
|
||||
let formattedTime = ""
|
||||
const date = new Date(params.row.requestDate);
|
||||
formattedTime = date.toLocaleTimeString('en-US', { month: 'long', day: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); // Example format
|
||||
return <DateField
|
||||
size='small'
|
||||
disabled
|
||||
defaultValue={dayjs(params.row.requestDate)}
|
||||
format="LL"
|
||||
/>
|
||||
} },
|
||||
{ field: 'download', headerName: '', flex:0.1,
|
||||
renderCell: (params) =>{
|
||||
|
||||
const handlePay = async () => {
|
||||
var paymentUrlRequest = await fetch('/api/requests/'+params.row.id+'/payment')
|
||||
//console.log(paymentUrlRequest);
|
||||
var paymentUrlJson = await paymentUrlRequest.json();
|
||||
var paymentUrl = paymentUrlJson.paymentUrl;
|
||||
window.open(paymentUrl);
|
||||
columns = [
|
||||
{ field: 'id', headerName: '', flex: 0.05, sortable: false, filterable: false},
|
||||
{ field: 'status', headerName: 'Status', flex: 0.15, filterable: false, sortable: false,
|
||||
renderCell: (params) => {
|
||||
if(params.row.completed){
|
||||
return <Check color="success" />
|
||||
}
|
||||
return (<>
|
||||
<Tooltip arrow title="View more details."><IconButton onClick={() => { router.push("/dashboard/requests/"+params.row.id)}} aria-label="accept" color="primary"><OpenInNew/></IconButton></Tooltip>
|
||||
{((params.row.accepted==true &¶ms.row.declined==false && params.row.paid==false) ? (
|
||||
<Tooltip arrow title="Pay for this request."><IconButton onClick={handlePay} aria-label="accept" color="success"><ShoppingCartCheckoutIcon/></IconButton></Tooltip>
|
||||
): null
|
||||
)}
|
||||
{((params.row.completed) ? (
|
||||
<Tooltip arrow title="Download requests assets."><IconButton aria-label="download" color="secondary"><Download/></IconButton></Tooltip>
|
||||
): null
|
||||
)}
|
||||
</>
|
||||
)
|
||||
} }
|
||||
];
|
||||
else if(params.row.paid){
|
||||
return <PriceCheckIcon color="success" />
|
||||
}
|
||||
else if(params.row.accepted && params.row.paid==false){
|
||||
return <PriceCheckIcon color="warning" />
|
||||
}
|
||||
else if(params.row.accepted && params.row.paid){
|
||||
return <AssignmentTurnedInIcon color="info" />
|
||||
}
|
||||
else if(params.row.declined){
|
||||
return <AssignmentLateIcon color="error" />
|
||||
}
|
||||
else{
|
||||
return <Refresh color="secondary" />
|
||||
}
|
||||
}
|
||||
},
|
||||
{ field: 'amount', headerName: 'Amount', flex: 0.15, sortable: false, filterable: false, renderCell: (params) => {
|
||||
return <CurrencyTextField size="small" fullWidth value={params.row.amount} currencySymbol="$" disabled />;
|
||||
}},
|
||||
{ field: 'actions', headerName: '', flex:0.1, sortable: false, filterable: false,
|
||||
renderCell: (params) =>{
|
||||
|
||||
const handlePay = async () => {
|
||||
var paymentUrlRequest = await fetch('/api/requests/'+params.row.id+'/payment')
|
||||
//console.log(paymentUrlRequest);
|
||||
var paymentUrlJson = await paymentUrlRequest.json();
|
||||
var paymentUrl = paymentUrlJson.paymentUrl;
|
||||
window.open(paymentUrl);
|
||||
}
|
||||
return (<>
|
||||
<Tooltip arrow title="View more details."><IconButton onClick={() => { router.push("/dashboard/requests/"+params.row.id)}} aria-label="accept" color="primary"><OpenInNew/></IconButton></Tooltip>
|
||||
{((params.row.accepted==true &¶ms.row.declined==false && params.row.paid==false) ? (
|
||||
<Tooltip arrow title="Pay for this request."><IconButton onClick={handlePay} aria-label="accept" color="success"><ShoppingCartCheckoutIcon/></IconButton></Tooltip>
|
||||
): null
|
||||
)}
|
||||
{((params.row.completed) ? (
|
||||
<Tooltip arrow title="Download requests assets."><IconButton aria-label="download" color="secondary"><Download/></IconButton></Tooltip>
|
||||
): null
|
||||
)}
|
||||
</>
|
||||
)
|
||||
} }
|
||||
];
|
||||
}
|
||||
else{
|
||||
|
||||
columns = [
|
||||
{ field: 'id', headerName: 'ID', flex: 0.1, sortable: false, filterable: false},
|
||||
{ field: 'status', headerName: 'Status', flex: 0.15, sortable: false, filterable: false,
|
||||
renderCell: (params) => {
|
||||
if(params.row.completed){
|
||||
return <Chip icon={<Check />} label="Completed" variant="outlined" color="success" />
|
||||
}
|
||||
else if(params.row.paid){
|
||||
return <Chip icon={<PriceCheckIcon />} label="Paid" variant="outlined" color="success" />
|
||||
}
|
||||
else if(params.row.accepted && params.row.paid==false){
|
||||
return <Chip icon={<PriceCheckIcon />} label="Pending Payment" variant="outlined" color="warning" />
|
||||
}
|
||||
else if(params.row.accepted && params.row.paid){
|
||||
return <Chip icon={<AssignmentTurnedInIcon />} label="Accepted" variant="outlined" color="info" />
|
||||
}
|
||||
else if(params.row.declined){
|
||||
return <Chip icon={<AssignmentLateIcon />} label="Declined" variant="outlined" color="error" />
|
||||
}
|
||||
else{
|
||||
return <Chip icon={<Refresh />} label="Pending" variant="outlined" color="secondary" />
|
||||
}
|
||||
}
|
||||
},
|
||||
{ field: 'message', headerName: 'Message', flex: 0.5, sortable: false, filterable: false,
|
||||
renderCell: (params) => {
|
||||
return <TextField size="small" fullWidth value={params.row.message} disabled />;
|
||||
}},
|
||||
{ field: 'amount', headerName: 'Amount', flex: 0.1, filterable: false, renderCell: (params) => {
|
||||
return <CurrencyTextField size="small" fullWidth value={params.row.amount} currencySymbol="$" disabled />;
|
||||
}},
|
||||
{ field: 'requestDate', headerName: 'Request Date', sortable: false, flex:0.15, filterable: false,
|
||||
renderCell: (params) =>{
|
||||
|
||||
let formattedTime = ""
|
||||
const date = new Date(params.row.requestDate);
|
||||
formattedTime = date.toLocaleTimeString('en-US', { month: 'long', day: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); // Example format
|
||||
return <DateField
|
||||
size='small'
|
||||
disabled
|
||||
defaultValue={dayjs(params.row.requestDate)}
|
||||
format="LL"
|
||||
/>
|
||||
} },
|
||||
{ field: 'download', headerName: '', sortable: false, flex:0.1, filterable: false,
|
||||
renderCell: (params) =>{
|
||||
|
||||
const handlePay = async () => {
|
||||
var paymentUrlRequest = await fetch('/api/requests/'+params.row.id+'/payment')
|
||||
//console.log(paymentUrlRequest);
|
||||
var paymentUrlJson = await paymentUrlRequest.json();
|
||||
var paymentUrl = paymentUrlJson.paymentUrl;
|
||||
window.open(paymentUrl);
|
||||
}
|
||||
return (<>
|
||||
<Tooltip arrow title="View more details."><IconButton onClick={() => { router.push("/dashboard/requests/"+params.row.id)}} aria-label="accept" color="primary"><OpenInNew/></IconButton></Tooltip>
|
||||
{((params.row.accepted==true &¶ms.row.declined==false && params.row.paid==false) ? (
|
||||
<Tooltip arrow title="Pay for this request."><IconButton onClick={handlePay} aria-label="accept" color="success"><ShoppingCartCheckoutIcon/></IconButton></Tooltip>
|
||||
): null
|
||||
)}
|
||||
{((params.row.completed) ? (
|
||||
<Tooltip arrow title="Download requests assets."><IconButton aria-label="download" color="secondary"><Download/></IconButton></Tooltip>
|
||||
): null
|
||||
)}
|
||||
</>
|
||||
)
|
||||
} }
|
||||
];
|
||||
}
|
||||
const [isLoading, setIsLoading] = React.useState(true);
|
||||
const [requestCount, setRequestCount] = React.useState(null);
|
||||
const [requestData, setRequestData] = React.useState({});
|
||||
|
@ -278,6 +278,15 @@ const RequestDetails = () => {
|
||||
disabled={!review || alreadyReviewed}
|
||||
onChange={handleRatingChange}/>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12}>
|
||||
{request.completed ? (
|
||||
request.reviewed ? (
|
||||
<Alert sx={{width:"100%"}} severity="info">You have reviewed this request so others know the quality of this artists work!</Alert>
|
||||
):(
|
||||
<Alert sx={{width:"100%"}} severity="warning">Please leave a review for this request so other users know the quality of this artists work!</Alert>
|
||||
)
|
||||
): null}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Paper>
|
||||
</Grid>
|
||||
@ -300,11 +309,12 @@ const RequestDetails = () => {
|
||||
)
|
||||
:(
|
||||
<>
|
||||
<Typography variant="h6" component="h6" gutterBottom>
|
||||
Loading...
|
||||
</Typography>
|
||||
<Box sx={{paddingTop:"20%"}}></Box>
|
||||
<CircularProgress/>
|
||||
<Box sx={{paddingTop:"20%", textAlign:"center"}}>
|
||||
<Typography variant="h6" component="h6" gutterBottom>
|
||||
Loading...
|
||||
</Typography>
|
||||
<CircularProgress/>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
@ -1,37 +0,0 @@
|
||||
// ** MUI Imports
|
||||
import Grid from '@mui/material/Grid'
|
||||
|
||||
// ** Styled Component
|
||||
import DatePickerWrapper from '../../core/styles/libs/react-datepicker'
|
||||
|
||||
// ** Demo Components Imports
|
||||
import FormLayoutsBasic from '../../views/form-layouts/FormLayoutsBasic'
|
||||
import FormLayoutsIcons from '../../views/form-layouts/FormLayoutsIcons'
|
||||
import FormLayoutsSeparator from '../../views/form-layouts/FormLayoutsSeparator'
|
||||
import FormLayoutsAlignment from '../../views/form-layouts/FormLayoutsAlignment'
|
||||
|
||||
// ** Third Party Styles Imports
|
||||
import 'react-datepicker/dist/react-datepicker.css'
|
||||
|
||||
const FormLayouts = () => {
|
||||
return (
|
||||
<DatePickerWrapper>
|
||||
<Grid container spacing={6}>
|
||||
<Grid item xs={12} md={6}>
|
||||
<FormLayoutsBasic />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<FormLayoutsIcons />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormLayoutsSeparator />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormLayoutsAlignment />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DatePickerWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export default FormLayouts
|
@ -1,164 +0,0 @@
|
||||
// ** MUI Imports
|
||||
import Grid from '@mui/material/Grid'
|
||||
import Card from '@mui/material/Card'
|
||||
import Link from '@mui/material/Link'
|
||||
import Button from '@mui/material/Button'
|
||||
import Tooltip from '@mui/material/Tooltip'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import CardContent from '@mui/material/CardContent'
|
||||
|
||||
/**
|
||||
** Icons Imports:
|
||||
* ! You need to import all the icons which come from the API or from your server and then add these icons in 'icons' variable.
|
||||
* ! If you need all the icons from the library, use "import * as Icon from 'mdi-material-ui'"
|
||||
* */
|
||||
import Abacus from 'mdi-material-ui/Abacus'
|
||||
import Account from 'mdi-material-ui/Account'
|
||||
import AbTesting from 'mdi-material-ui/AbTesting'
|
||||
import AccountBox from 'mdi-material-ui/AccountBox'
|
||||
import AccountCog from 'mdi-material-ui/AccountCog'
|
||||
import AbjadArabic from 'mdi-material-ui/AbjadArabic'
|
||||
import AbjadHebrew from 'mdi-material-ui/AbjadHebrew'
|
||||
import AbugidaThai from 'mdi-material-ui/AbugidaThai'
|
||||
import AccessPoint from 'mdi-material-ui/AccessPoint'
|
||||
import AccountCash from 'mdi-material-ui/AccountCash'
|
||||
import AccountEdit from 'mdi-material-ui/AccountEdit'
|
||||
import AccountAlert from 'mdi-material-ui/AccountAlert'
|
||||
import AccountCheck from 'mdi-material-ui/AccountCheck'
|
||||
import AccountChild from 'mdi-material-ui/AccountChild'
|
||||
import AccountClock from 'mdi-material-ui/AccountClock'
|
||||
import AccountGroup from 'mdi-material-ui/AccountGroup'
|
||||
import AccountCancel from 'mdi-material-ui/AccountCancel'
|
||||
import AccountCircle from 'mdi-material-ui/AccountCircle'
|
||||
import AccessPointOff from 'mdi-material-ui/AccessPointOff'
|
||||
import AccountConvert from 'mdi-material-ui/AccountConvert'
|
||||
import AccountDetails from 'mdi-material-ui/AccountDetails'
|
||||
import AccessPointPlus from 'mdi-material-ui/AccessPointPlus'
|
||||
import AccessPointCheck from 'mdi-material-ui/AccessPointCheck'
|
||||
import AccessPointMinus from 'mdi-material-ui/AccessPointMinus'
|
||||
import AccountArrowLeft from 'mdi-material-ui/AccountArrowLeft'
|
||||
import AccountCowboyHat from 'mdi-material-ui/AccountCowboyHat'
|
||||
import AbugidaDevanagari from 'mdi-material-ui/AbugidaDevanagari'
|
||||
import AccessPointRemove from 'mdi-material-ui/AccessPointRemove'
|
||||
import AccountArrowRight from 'mdi-material-ui/AccountArrowRight'
|
||||
import AccountBoxOutline from 'mdi-material-ui/AccountBoxOutline'
|
||||
import AccountCogOutline from 'mdi-material-ui/AccountCogOutline'
|
||||
import AccessPointNetwork from 'mdi-material-ui/AccessPointNetwork'
|
||||
import AccountBoxMultiple from 'mdi-material-ui/AccountBoxMultiple'
|
||||
import AccountCashOutline from 'mdi-material-ui/AccountCashOutline'
|
||||
import AccountChildCircle from 'mdi-material-ui/AccountChildCircle'
|
||||
import AccountEditOutline from 'mdi-material-ui/AccountEditOutline'
|
||||
import AccountAlertOutline from 'mdi-material-ui/AccountAlertOutline'
|
||||
import AccountCheckOutline from 'mdi-material-ui/AccountCheckOutline'
|
||||
import AccountChildOutline from 'mdi-material-ui/AccountChildOutline'
|
||||
import AccountClockOutline from 'mdi-material-ui/AccountClockOutline'
|
||||
import AccountCancelOutline from 'mdi-material-ui/AccountCancelOutline'
|
||||
import AccountCircleOutline from 'mdi-material-ui/AccountCircleOutline'
|
||||
import AccessPointNetworkOff from 'mdi-material-ui/AccessPointNetworkOff'
|
||||
import AccountConvertOutline from 'mdi-material-ui/AccountConvertOutline'
|
||||
import AccountDetailsOutline from 'mdi-material-ui/AccountDetailsOutline'
|
||||
import AccountArrowLeftOutline from 'mdi-material-ui/AccountArrowLeftOutline'
|
||||
import AccountArrowRightOutline from 'mdi-material-ui/AccountArrowRightOutline'
|
||||
import AccountBoxMultipleOutline from 'mdi-material-ui/AccountBoxMultipleOutline'
|
||||
|
||||
const icons = {
|
||||
Abacus,
|
||||
Account,
|
||||
AbTesting,
|
||||
AccountBox,
|
||||
AccountCog,
|
||||
AbjadArabic,
|
||||
AbjadHebrew,
|
||||
AbugidaThai,
|
||||
AccessPoint,
|
||||
AccountCash,
|
||||
AccountEdit,
|
||||
AccountAlert,
|
||||
AccountCheck,
|
||||
AccountChild,
|
||||
AccountClock,
|
||||
AccountGroup,
|
||||
AccountCancel,
|
||||
AccountCircle,
|
||||
AccessPointOff,
|
||||
AccountConvert,
|
||||
AccountDetails,
|
||||
AccessPointPlus,
|
||||
AccessPointCheck,
|
||||
AccessPointMinus,
|
||||
AccountArrowLeft,
|
||||
AccountCowboyHat,
|
||||
AbugidaDevanagari,
|
||||
AccessPointRemove,
|
||||
AccountArrowRight,
|
||||
AccountBoxOutline,
|
||||
AccountCogOutline,
|
||||
AccessPointNetwork,
|
||||
AccountBoxMultiple,
|
||||
AccountCashOutline,
|
||||
AccountChildCircle,
|
||||
AccountEditOutline,
|
||||
AccountAlertOutline,
|
||||
AccountCheckOutline,
|
||||
AccountChildOutline,
|
||||
AccountClockOutline,
|
||||
AccountCancelOutline,
|
||||
AccountCircleOutline,
|
||||
AccessPointNetworkOff,
|
||||
AccountConvertOutline,
|
||||
AccountDetailsOutline,
|
||||
AccountArrowLeftOutline,
|
||||
AccountArrowRightOutline,
|
||||
AccountBoxMultipleOutline
|
||||
}
|
||||
|
||||
const Icons = () => {
|
||||
const renderIconGrids = () => {
|
||||
return Object.keys(icons).map(key => {
|
||||
const IconTag = icons[key as keyof typeof icons]
|
||||
|
||||
return (
|
||||
<Grid item key={key}>
|
||||
<Tooltip arrow title={key} placement='top'>
|
||||
<Card>
|
||||
<CardContent sx={{ display: 'flex' }}>
|
||||
<IconTag />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid container spacing={6}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant='h5'>
|
||||
<Link href='https://materialdesignicons.com/' target='_blank'>
|
||||
Material Design Icons
|
||||
</Link>
|
||||
</Typography>
|
||||
<Typography variant='body2'>Material Design Icons from the Community</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid container spacing={6}>
|
||||
{renderIconGrids()}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{ textAlign: 'center' }}>
|
||||
<Button
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
component={Link}
|
||||
variant='contained'
|
||||
href='https://materialdesignicons.com/'
|
||||
>
|
||||
View All Material Design Icons
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
export default Icons
|
@ -1,14 +0,0 @@
|
||||
// ** React Imports
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
// ** Layout Import
|
||||
import BlankLayout from '../core/layouts/BlankLayout'
|
||||
|
||||
// ** Component Import
|
||||
import Error404 from '../pages/404'
|
||||
|
||||
const ErrorPage = () => <Error404 />
|
||||
|
||||
ErrorPage.getLayout = (page: ReactNode) => <BlankLayout>{page}</BlankLayout>
|
||||
|
||||
export default ErrorPage
|
@ -1,257 +0,0 @@
|
||||
// ** React Imports
|
||||
import { ChangeEvent, MouseEvent, ReactNode, useState } from 'react'
|
||||
|
||||
// ** Next Imports
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
// ** MUI Components
|
||||
import Box from '@mui/material/Box'
|
||||
import Button from '@mui/material/Button'
|
||||
import Divider from '@mui/material/Divider'
|
||||
import Checkbox from '@mui/material/Checkbox'
|
||||
import TextField from '@mui/material/TextField'
|
||||
import InputLabel from '@mui/material/InputLabel'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import CardContent from '@mui/material/CardContent'
|
||||
import FormControl from '@mui/material/FormControl'
|
||||
import OutlinedInput from '@mui/material/OutlinedInput'
|
||||
import { styled, useTheme } from '@mui/material/styles'
|
||||
import MuiCard, { CardProps } from '@mui/material/Card'
|
||||
import InputAdornment from '@mui/material/InputAdornment'
|
||||
import MuiFormControlLabel, { FormControlLabelProps } from '@mui/material/FormControlLabel'
|
||||
|
||||
// ** Icons Imports
|
||||
import Google from 'mdi-material-ui/Google'
|
||||
import Github from 'mdi-material-ui/Github'
|
||||
import Twitter from 'mdi-material-ui/Twitter'
|
||||
import Facebook from 'mdi-material-ui/Facebook'
|
||||
import EyeOutline from 'mdi-material-ui/EyeOutline'
|
||||
import EyeOffOutline from 'mdi-material-ui/EyeOffOutline'
|
||||
|
||||
// ** Configs
|
||||
import themeConfig from '../configs/themeConfig'
|
||||
|
||||
// ** Layout Import
|
||||
import BlankLayout from '../core/layouts/BlankLayout'
|
||||
|
||||
// ** Demo Imports
|
||||
import FooterIllustrationsV1 from '../views/pages/auth/FooterIllustration'
|
||||
|
||||
interface State {
|
||||
password: string
|
||||
showPassword: boolean
|
||||
}
|
||||
|
||||
// ** Styled Components
|
||||
const Card = styled(MuiCard)<CardProps>(({ theme }) => ({
|
||||
[theme.breakpoints.up('sm')]: { width: '28rem' }
|
||||
}))
|
||||
|
||||
const LinkStyled = styled('a')(({ theme }) => ({
|
||||
fontSize: '0.875rem',
|
||||
textDecoration: 'none',
|
||||
color: theme.palette.primary.main
|
||||
}))
|
||||
|
||||
const FormControlLabel = styled(MuiFormControlLabel)<FormControlLabelProps>(({ theme }) => ({
|
||||
'& .MuiFormControlLabel-label': {
|
||||
fontSize: '0.875rem',
|
||||
color: theme.palette.text.secondary
|
||||
}
|
||||
}))
|
||||
|
||||
const LoginPage = () => {
|
||||
// ** State
|
||||
const [values, setValues] = useState<State>({
|
||||
password: '',
|
||||
showPassword: false
|
||||
})
|
||||
|
||||
// ** Hook
|
||||
const theme = useTheme()
|
||||
const router = useRouter()
|
||||
|
||||
const handleChange = (prop: keyof State) => (event: ChangeEvent<HTMLInputElement>) => {
|
||||
setValues({ ...values, [prop]: event.target.value })
|
||||
}
|
||||
|
||||
const handleClickShowPassword = () => {
|
||||
setValues({ ...values, showPassword: !values.showPassword })
|
||||
}
|
||||
|
||||
const handleMouseDownPassword = (event: MouseEvent<HTMLButtonElement>) => {
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
return (
|
||||
<Box className='content-center'>
|
||||
<Card sx={{ zIndex: 1 }}>
|
||||
<CardContent sx={{ padding: theme => `${theme.spacing(12, 9, 7)} !important` }}>
|
||||
<Box sx={{ mb: 8, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<svg
|
||||
width={35}
|
||||
height={29}
|
||||
version='1.1'
|
||||
viewBox='0 0 30 23'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
xmlnsXlink='http://www.w3.org/1999/xlink'
|
||||
>
|
||||
<g stroke='none' strokeWidth='1' fill='none' fillRule='evenodd'>
|
||||
<g id='Artboard' transform='translate(-95.000000, -51.000000)'>
|
||||
<g id='logo' transform='translate(95.000000, 50.000000)'>
|
||||
<path
|
||||
id='Combined-Shape'
|
||||
fill={theme.palette.primary.main}
|
||||
d='M30,21.3918362 C30,21.7535219 29.9019196,22.1084381 29.7162004,22.4188007 C29.1490236,23.366632 27.9208668,23.6752135 26.9730355,23.1080366 L26.9730355,23.1080366 L23.714971,21.1584295 C23.1114106,20.7972624 22.7419355,20.1455972 22.7419355,19.4422291 L22.7419355,19.4422291 L22.741,12.7425689 L15,17.1774194 L7.258,12.7425689 L7.25806452,19.4422291 C7.25806452,20.1455972 6.88858935,20.7972624 6.28502902,21.1584295 L3.0269645,23.1080366 C2.07913318,23.6752135 0.850976404,23.366632 0.283799571,22.4188007 C0.0980803893,22.1084381 2.0190442e-15,21.7535219 0,21.3918362 L0,3.58469444 L0.00548573643,3.43543209 L0.00548573643,3.43543209 L0,3.5715689 C3.0881846e-16,2.4669994 0.8954305,1.5715689 2,1.5715689 C2.36889529,1.5715689 2.73060353,1.67359571 3.04512412,1.86636639 L15,9.19354839 L26.9548759,1.86636639 C27.2693965,1.67359571 27.6311047,1.5715689 28,1.5715689 C29.1045695,1.5715689 30,2.4669994 30,3.5715689 L30,3.5715689 Z'
|
||||
/>
|
||||
<polygon
|
||||
id='Rectangle'
|
||||
opacity='0.077704'
|
||||
fill={theme.palette.common.black}
|
||||
points='0 8.58870968 7.25806452 12.7505183 7.25806452 16.8305646'
|
||||
/>
|
||||
<polygon
|
||||
id='Rectangle'
|
||||
opacity='0.077704'
|
||||
fill={theme.palette.common.black}
|
||||
points='0 8.58870968 7.25806452 12.6445567 7.25806452 15.1370162'
|
||||
/>
|
||||
<polygon
|
||||
id='Rectangle'
|
||||
opacity='0.077704'
|
||||
fill={theme.palette.common.black}
|
||||
points='22.7419355 8.58870968 30 12.7417372 30 16.9537453'
|
||||
transform='translate(26.370968, 12.771227) scale(-1, 1) translate(-26.370968, -12.771227) '
|
||||
/>
|
||||
<polygon
|
||||
id='Rectangle'
|
||||
opacity='0.077704'
|
||||
fill={theme.palette.common.black}
|
||||
points='22.7419355 8.58870968 30 12.6409734 30 15.2601969'
|
||||
transform='translate(26.370968, 11.924453) scale(-1, 1) translate(-26.370968, -11.924453) '
|
||||
/>
|
||||
<path
|
||||
id='Rectangle'
|
||||
fillOpacity='0.15'
|
||||
fill={theme.palette.common.white}
|
||||
d='M3.04512412,1.86636639 L15,9.19354839 L15,9.19354839 L15,17.1774194 L0,8.58649679 L0,3.5715689 C3.0881846e-16,2.4669994 0.8954305,1.5715689 2,1.5715689 C2.36889529,1.5715689 2.73060353,1.67359571 3.04512412,1.86636639 Z'
|
||||
/>
|
||||
<path
|
||||
id='Rectangle'
|
||||
fillOpacity='0.35'
|
||||
fill={theme.palette.common.white}
|
||||
transform='translate(22.500000, 8.588710) scale(-1, 1) translate(-22.500000, -8.588710) '
|
||||
d='M18.0451241,1.86636639 L30,9.19354839 L30,9.19354839 L30,17.1774194 L15,8.58649679 L15,3.5715689 C15,2.4669994 15.8954305,1.5715689 17,1.5715689 C17.3688953,1.5715689 17.7306035,1.67359571 18.0451241,1.86636639 Z'
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<Typography
|
||||
variant='h6'
|
||||
sx={{
|
||||
ml: 3,
|
||||
lineHeight: 1,
|
||||
fontWeight: 600,
|
||||
textTransform: 'uppercase',
|
||||
fontSize: '1.5rem !important'
|
||||
}}
|
||||
>
|
||||
{themeConfig.templateName}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{ mb: 6 }}>
|
||||
<Typography variant='h5' sx={{ fontWeight: 600, marginBottom: 1.5 }}>
|
||||
Welcome to {themeConfig.templateName}! 👋🏻
|
||||
</Typography>
|
||||
<Typography variant='body2'>Please sign-in to your account and start the adventure</Typography>
|
||||
</Box>
|
||||
<form noValidate autoComplete='off' onSubmit={e => e.preventDefault()}>
|
||||
<TextField autoFocus fullWidth id='email' label='Email' sx={{ marginBottom: 4 }} />
|
||||
<FormControl fullWidth>
|
||||
<InputLabel htmlFor='auth-login-password'>Password</InputLabel>
|
||||
<OutlinedInput
|
||||
label='Password'
|
||||
value={values.password}
|
||||
id='auth-login-password'
|
||||
onChange={handleChange('password')}
|
||||
type={values.showPassword ? 'text' : 'password'}
|
||||
endAdornment={
|
||||
<InputAdornment position='end'>
|
||||
<IconButton
|
||||
edge='end'
|
||||
onClick={handleClickShowPassword}
|
||||
onMouseDown={handleMouseDownPassword}
|
||||
aria-label='toggle password visibility'
|
||||
>
|
||||
{values.showPassword ? <EyeOutline /> : <EyeOffOutline />}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
</FormControl>
|
||||
<Box
|
||||
sx={{ mb: 4, display: 'flex', alignItems: 'center', flexWrap: 'wrap', justifyContent: 'space-between' }}
|
||||
>
|
||||
<FormControlLabel control={<Checkbox />} label='Remember Me' />
|
||||
<Link passHref href='/'>
|
||||
<LinkStyled onClick={e => e.preventDefault()}>Forgot Password?</LinkStyled>
|
||||
</Link>
|
||||
</Box>
|
||||
<Button
|
||||
fullWidth
|
||||
size='large'
|
||||
variant='contained'
|
||||
sx={{ marginBottom: 7 }}
|
||||
onClick={() => router.push('/')}
|
||||
>
|
||||
Login
|
||||
</Button>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', justifyContent: 'center' }}>
|
||||
<Typography variant='body2' sx={{ marginRight: 2 }}>
|
||||
New on our platform?
|
||||
</Typography>
|
||||
<Typography variant='body2'>
|
||||
<Link passHref href='/pages/register'>
|
||||
<LinkStyled>Create an account</LinkStyled>
|
||||
</Link>
|
||||
</Typography>
|
||||
</Box>
|
||||
<Divider sx={{ my: 5 }}>or</Divider>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<Link href='/' passHref>
|
||||
<IconButton component='a' onClick={(e: MouseEvent<HTMLElement>) => e.preventDefault()}>
|
||||
<Facebook sx={{ color: '#497ce2' }} />
|
||||
</IconButton>
|
||||
</Link>
|
||||
<Link href='/' passHref>
|
||||
<IconButton component='a' onClick={(e: MouseEvent<HTMLElement>) => e.preventDefault()}>
|
||||
<Twitter sx={{ color: '#1da1f2' }} />
|
||||
</IconButton>
|
||||
</Link>
|
||||
<Link href='/' passHref>
|
||||
<IconButton component='a' onClick={(e: MouseEvent<HTMLElement>) => e.preventDefault()}>
|
||||
<Github
|
||||
sx={{ color: theme => (theme.palette.mode === 'light' ? '#272727' : theme.palette.grey[300]) }}
|
||||
/>
|
||||
</IconButton>
|
||||
</Link>
|
||||
<Link href='/' passHref>
|
||||
<IconButton component='a' onClick={(e: MouseEvent<HTMLElement>) => e.preventDefault()}>
|
||||
<Google sx={{ color: '#db4437' }} />
|
||||
</IconButton>
|
||||
</Link>
|
||||
</Box>
|
||||
</form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<FooterIllustrationsV1 />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
LoginPage.getLayout = (page: ReactNode) => <BlankLayout>{page}</BlankLayout>
|
||||
|
||||
export default LoginPage
|
@ -1,255 +0,0 @@
|
||||
// ** React Imports
|
||||
import { useState, Fragment, ChangeEvent, MouseEvent, ReactNode } from 'react'
|
||||
|
||||
// ** Next Imports
|
||||
import Link from 'next/link'
|
||||
|
||||
// ** MUI Components
|
||||
import Box from '@mui/material/Box'
|
||||
import Button from '@mui/material/Button'
|
||||
import Divider from '@mui/material/Divider'
|
||||
import Checkbox from '@mui/material/Checkbox'
|
||||
import TextField from '@mui/material/TextField'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import InputLabel from '@mui/material/InputLabel'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import CardContent from '@mui/material/CardContent'
|
||||
import FormControl from '@mui/material/FormControl'
|
||||
import OutlinedInput from '@mui/material/OutlinedInput'
|
||||
import { styled, useTheme } from '@mui/material/styles'
|
||||
import MuiCard, { CardProps } from '@mui/material/Card'
|
||||
import InputAdornment from '@mui/material/InputAdornment'
|
||||
import MuiFormControlLabel, { FormControlLabelProps } from '@mui/material/FormControlLabel'
|
||||
|
||||
// ** Icons Imports
|
||||
import Google from 'mdi-material-ui/Google'
|
||||
import Github from 'mdi-material-ui/Github'
|
||||
import Twitter from 'mdi-material-ui/Twitter'
|
||||
import Facebook from 'mdi-material-ui/Facebook'
|
||||
import EyeOutline from 'mdi-material-ui/EyeOutline'
|
||||
import EyeOffOutline from 'mdi-material-ui/EyeOffOutline'
|
||||
|
||||
// ** Configs
|
||||
import themeConfig from '../configs/themeConfig'
|
||||
|
||||
// ** Layout Import
|
||||
import BlankLayout from '../core/layouts/BlankLayout'
|
||||
|
||||
// ** Demo Imports
|
||||
import FooterIllustrationsV1 from '../views/pages/auth/FooterIllustration'
|
||||
|
||||
interface State {
|
||||
password: string
|
||||
showPassword: boolean
|
||||
}
|
||||
|
||||
// ** Styled Components
|
||||
const Card = styled(MuiCard)<CardProps>(({ theme }) => ({
|
||||
[theme.breakpoints.up('sm')]: { width: '28rem' }
|
||||
}))
|
||||
|
||||
const LinkStyled = styled('a')(({ theme }) => ({
|
||||
fontSize: '0.875rem',
|
||||
textDecoration: 'none',
|
||||
color: theme.palette.primary.main
|
||||
}))
|
||||
|
||||
const FormControlLabel = styled(MuiFormControlLabel)<FormControlLabelProps>(({ theme }) => ({
|
||||
marginTop: theme.spacing(1.5),
|
||||
marginBottom: theme.spacing(4),
|
||||
'& .MuiFormControlLabel-label': {
|
||||
fontSize: '0.875rem',
|
||||
color: theme.palette.text.secondary
|
||||
}
|
||||
}))
|
||||
|
||||
const RegisterPage = () => {
|
||||
// ** States
|
||||
const [values, setValues] = useState<State>({
|
||||
password: '',
|
||||
showPassword: false
|
||||
})
|
||||
|
||||
// ** Hook
|
||||
const theme = useTheme()
|
||||
|
||||
const handleChange = (prop: keyof State) => (event: ChangeEvent<HTMLInputElement>) => {
|
||||
setValues({ ...values, [prop]: event.target.value })
|
||||
}
|
||||
const handleClickShowPassword = () => {
|
||||
setValues({ ...values, showPassword: !values.showPassword })
|
||||
}
|
||||
const handleMouseDownPassword = (event: MouseEvent<HTMLButtonElement>) => {
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
return (
|
||||
<Box className='content-center'>
|
||||
<Card sx={{ zIndex: 1 }}>
|
||||
<CardContent sx={{ padding: theme => `${theme.spacing(12, 9, 7)} !important` }}>
|
||||
<Box sx={{ mb: 8, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<svg
|
||||
width={35}
|
||||
height={29}
|
||||
version='1.1'
|
||||
viewBox='0 0 30 23'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
xmlnsXlink='http://www.w3.org/1999/xlink'
|
||||
>
|
||||
<g stroke='none' strokeWidth='1' fill='none' fillRule='evenodd'>
|
||||
<g id='Artboard' transform='translate(-95.000000, -51.000000)'>
|
||||
<g id='logo' transform='translate(95.000000, 50.000000)'>
|
||||
<path
|
||||
id='Combined-Shape'
|
||||
fill={theme.palette.primary.main}
|
||||
d='M30,21.3918362 C30,21.7535219 29.9019196,22.1084381 29.7162004,22.4188007 C29.1490236,23.366632 27.9208668,23.6752135 26.9730355,23.1080366 L26.9730355,23.1080366 L23.714971,21.1584295 C23.1114106,20.7972624 22.7419355,20.1455972 22.7419355,19.4422291 L22.7419355,19.4422291 L22.741,12.7425689 L15,17.1774194 L7.258,12.7425689 L7.25806452,19.4422291 C7.25806452,20.1455972 6.88858935,20.7972624 6.28502902,21.1584295 L3.0269645,23.1080366 C2.07913318,23.6752135 0.850976404,23.366632 0.283799571,22.4188007 C0.0980803893,22.1084381 2.0190442e-15,21.7535219 0,21.3918362 L0,3.58469444 L0.00548573643,3.43543209 L0.00548573643,3.43543209 L0,3.5715689 C3.0881846e-16,2.4669994 0.8954305,1.5715689 2,1.5715689 C2.36889529,1.5715689 2.73060353,1.67359571 3.04512412,1.86636639 L15,9.19354839 L26.9548759,1.86636639 C27.2693965,1.67359571 27.6311047,1.5715689 28,1.5715689 C29.1045695,1.5715689 30,2.4669994 30,3.5715689 L30,3.5715689 Z'
|
||||
/>
|
||||
<polygon
|
||||
id='Rectangle'
|
||||
opacity='0.077704'
|
||||
fill={theme.palette.common.black}
|
||||
points='0 8.58870968 7.25806452 12.7505183 7.25806452 16.8305646'
|
||||
/>
|
||||
<polygon
|
||||
id='Rectangle'
|
||||
opacity='0.077704'
|
||||
fill={theme.palette.common.black}
|
||||
points='0 8.58870968 7.25806452 12.6445567 7.25806452 15.1370162'
|
||||
/>
|
||||
<polygon
|
||||
id='Rectangle'
|
||||
opacity='0.077704'
|
||||
fill={theme.palette.common.black}
|
||||
points='22.7419355 8.58870968 30 12.7417372 30 16.9537453'
|
||||
transform='translate(26.370968, 12.771227) scale(-1, 1) translate(-26.370968, -12.771227) '
|
||||
/>
|
||||
<polygon
|
||||
id='Rectangle'
|
||||
opacity='0.077704'
|
||||
fill={theme.palette.common.black}
|
||||
points='22.7419355 8.58870968 30 12.6409734 30 15.2601969'
|
||||
transform='translate(26.370968, 11.924453) scale(-1, 1) translate(-26.370968, -11.924453) '
|
||||
/>
|
||||
<path
|
||||
id='Rectangle'
|
||||
fillOpacity='0.15'
|
||||
fill={theme.palette.common.white}
|
||||
d='M3.04512412,1.86636639 L15,9.19354839 L15,9.19354839 L15,17.1774194 L0,8.58649679 L0,3.5715689 C3.0881846e-16,2.4669994 0.8954305,1.5715689 2,1.5715689 C2.36889529,1.5715689 2.73060353,1.67359571 3.04512412,1.86636639 Z'
|
||||
/>
|
||||
<path
|
||||
id='Rectangle'
|
||||
fillOpacity='0.35'
|
||||
fill={theme.palette.common.white}
|
||||
transform='translate(22.500000, 8.588710) scale(-1, 1) translate(-22.500000, -8.588710) '
|
||||
d='M18.0451241,1.86636639 L30,9.19354839 L30,9.19354839 L30,17.1774194 L15,8.58649679 L15,3.5715689 C15,2.4669994 15.8954305,1.5715689 17,1.5715689 C17.3688953,1.5715689 17.7306035,1.67359571 18.0451241,1.86636639 Z'
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<Typography
|
||||
variant='h6'
|
||||
sx={{
|
||||
ml: 3,
|
||||
lineHeight: 1,
|
||||
fontWeight: 600,
|
||||
textTransform: 'uppercase',
|
||||
fontSize: '1.5rem !important'
|
||||
}}
|
||||
>
|
||||
{themeConfig.templateName}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{ mb: 6 }}>
|
||||
<Typography variant='h5' sx={{ fontWeight: 600, marginBottom: 1.5 }}>
|
||||
Adventure starts here 🚀
|
||||
</Typography>
|
||||
<Typography variant='body2'>Make your app management easy and fun!</Typography>
|
||||
</Box>
|
||||
<form noValidate autoComplete='off' onSubmit={e => e.preventDefault()}>
|
||||
<TextField autoFocus fullWidth id='username' label='Username' sx={{ marginBottom: 4 }} />
|
||||
<TextField fullWidth type='email' label='Email' sx={{ marginBottom: 4 }} />
|
||||
<FormControl fullWidth>
|
||||
<InputLabel htmlFor='auth-register-password'>Password</InputLabel>
|
||||
<OutlinedInput
|
||||
label='Password'
|
||||
value={values.password}
|
||||
id='auth-register-password'
|
||||
onChange={handleChange('password')}
|
||||
type={values.showPassword ? 'text' : 'password'}
|
||||
endAdornment={
|
||||
<InputAdornment position='end'>
|
||||
<IconButton
|
||||
edge='end'
|
||||
onClick={handleClickShowPassword}
|
||||
onMouseDown={handleMouseDownPassword}
|
||||
aria-label='toggle password visibility'
|
||||
>
|
||||
{values.showPassword ? <EyeOutline fontSize='small' /> : <EyeOffOutline fontSize='small' />}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControlLabel
|
||||
control={<Checkbox />}
|
||||
label={
|
||||
<Fragment>
|
||||
<span>I agree to </span>
|
||||
<Link href='/' passHref>
|
||||
<LinkStyled onClick={(e: MouseEvent<HTMLElement>) => e.preventDefault()}>
|
||||
privacy policy & terms
|
||||
</LinkStyled>
|
||||
</Link>
|
||||
</Fragment>
|
||||
}
|
||||
/>
|
||||
<Button fullWidth size='large' type='submit' variant='contained' sx={{ marginBottom: 7 }}>
|
||||
Sign up
|
||||
</Button>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', justifyContent: 'center' }}>
|
||||
<Typography variant='body2' sx={{ marginRight: 2 }}>
|
||||
Already have an account?
|
||||
</Typography>
|
||||
<Typography variant='body2'>
|
||||
<Link passHref href='/pages/login'>
|
||||
<LinkStyled>Sign in instead</LinkStyled>
|
||||
</Link>
|
||||
</Typography>
|
||||
</Box>
|
||||
<Divider sx={{ my: 5 }}>or</Divider>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<Link href='/' passHref>
|
||||
<IconButton component='a' onClick={(e: MouseEvent<HTMLElement>) => e.preventDefault()}>
|
||||
<Facebook sx={{ color: '#497ce2' }} />
|
||||
</IconButton>
|
||||
</Link>
|
||||
<Link href='/' passHref>
|
||||
<IconButton component='a' onClick={(e: MouseEvent<HTMLElement>) => e.preventDefault()}>
|
||||
<Twitter sx={{ color: '#1da1f2' }} />
|
||||
</IconButton>
|
||||
</Link>
|
||||
<Link href='/' passHref>
|
||||
<IconButton component='a' onClick={(e: MouseEvent<HTMLElement>) => e.preventDefault()}>
|
||||
<Github
|
||||
sx={{ color: theme => (theme.palette.mode === 'light' ? '#272727' : theme.palette.grey[300]) }}
|
||||
/>
|
||||
</IconButton>
|
||||
</Link>
|
||||
<Link href='/' passHref>
|
||||
<IconButton component='a' onClick={(e: MouseEvent<HTMLElement>) => e.preventDefault()}>
|
||||
<Google sx={{ color: '#db4437' }} />
|
||||
</IconButton>
|
||||
</Link>
|
||||
</Box>
|
||||
</form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<FooterIllustrationsV1 />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
RegisterPage.getLayout = (page: ReactNode) => <BlankLayout>{page}</BlankLayout>
|
||||
|
||||
export default RegisterPage
|
@ -1,67 +0,0 @@
|
||||
// ** MUI Imports
|
||||
import Grid from '@mui/material/Grid'
|
||||
import Link from '@mui/material/Link'
|
||||
import Card from '@mui/material/Card'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import CardHeader from '@mui/material/CardHeader'
|
||||
|
||||
// ** Demo Components Imports
|
||||
import TableBasic from '../views/tables/TableBasic'
|
||||
import TableDense from '../views/tables/TableDense'
|
||||
import TableSpanning from '../views/tables/TableSpanning'
|
||||
import TableCustomized from '../views/tables/TableCustomized'
|
||||
import TableCollapsible from '../views/tables/TableCollapsible'
|
||||
import TableStickyHeader from '../views/tables/TableStickyHeader'
|
||||
|
||||
const MUITable = () => {
|
||||
return (
|
||||
<Grid container spacing={6}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant='h5'>
|
||||
<Link href='https://mui.com/components/tables/' target='_blank'>
|
||||
MUI Tables
|
||||
</Link>
|
||||
</Typography>
|
||||
<Typography variant='body2'>Tables display sets of data. They can be fully customized</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Card>
|
||||
<CardHeader title='Basic Table' titleTypographyProps={{ variant: 'h6' }} />
|
||||
<TableBasic />
|
||||
</Card>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Card>
|
||||
<CardHeader title='Dense Table' titleTypographyProps={{ variant: 'h6' }} />
|
||||
<TableDense />
|
||||
</Card>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Card>
|
||||
<CardHeader title='Sticky Header' titleTypographyProps={{ variant: 'h6' }} />
|
||||
<TableStickyHeader />
|
||||
</Card>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Card>
|
||||
<CardHeader title='Collapsible Table' titleTypographyProps={{ variant: 'h6' }} />
|
||||
<TableCollapsible />
|
||||
</Card>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Card>
|
||||
<CardHeader title='Spanning Table' titleTypographyProps={{ variant: 'h6' }} />
|
||||
<TableSpanning />
|
||||
</Card>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Card>
|
||||
<CardHeader title='Customized Table' titleTypographyProps={{ variant: 'h6' }} />
|
||||
<TableCustomized />
|
||||
</Card>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
export default MUITable
|
@ -1,21 +0,0 @@
|
||||
// ** MUI Imports
|
||||
import Grid from '@mui/material/Grid'
|
||||
|
||||
// ** Demo Components Imports
|
||||
import TypographyTexts from '../views/typography/TypographyTexts'
|
||||
import TypographyHeadings from '../views/typography/TypographyHeadings'
|
||||
|
||||
const TypographyPage = () => {
|
||||
return (
|
||||
<Grid container spacing={6}>
|
||||
<Grid item xs={12}>
|
||||
<TypographyHeadings />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<TypographyTexts />
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
export default TypographyPage
|
Loading…
x
Reference in New Issue
Block a user