mirror of
				https://github.com/D4M13N-D3V/comissions-app-ui.git
				synced 2025-10-31 01:25:22 +00:00 
			
		
		
		
	init
This commit is contained in:
		
						commit
						45ddebb984
					
				
							
								
								
									
										5
									
								
								.env.local.example
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.env.local.example
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| AUTH0_ISSUER_BASE_URL="https://" | ||||
| AUTH0_CLIENT_ID= | ||||
| AUTH0_CLIENT_SECRET= | ||||
| AUTH0_BASE_URL="http://localhost:3000" | ||||
| AUTH0_SECRET= | ||||
							
								
								
									
										14
									
								
								.github/workflows/on-pr.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/on-pr.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| name: on-pr | ||||
| on: [pull_request] | ||||
| 
 | ||||
| jobs: | ||||
|   unit-test: | ||||
|     runs-on: [Ubuntu-Latest] | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|        | ||||
|       - name: Install modules | ||||
|         run: npm install | ||||
|          | ||||
|       - name: Run tests | ||||
|         run: npm run test | ||||
							
								
								
									
										49
									
								
								.github/workflows/on-push.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								.github/workflows/on-push.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| name: on-pushed | ||||
| on: | ||||
|   push: | ||||
|     branches: [main] | ||||
| 
 | ||||
| jobs: | ||||
|   build-image: | ||||
|     runs-on: [ubuntu-latest] | ||||
|     permissions: write-all | ||||
|     env: | ||||
|       docker_image_name: ghcr.io/data443/dim-search-web-ui | ||||
|     steps: | ||||
| 
 | ||||
|     - uses: gittools/actions/gitversion/setup@v0.9.15 | ||||
|       with: | ||||
|         versionSpec: '5.x' | ||||
|            | ||||
|     - uses: actions/checkout@v3 | ||||
|       with: | ||||
|         fetch-depth: 0 | ||||
| 
 | ||||
|     - uses: gittools/actions/gitversion/execute@v0.9.15 | ||||
|       with: | ||||
|         useConfigFile: true | ||||
|         configFilePath: GitVersion.yml | ||||
|      | ||||
|     - name: login | ||||
|       run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login https://ghcr.io -u $ --password-stdin | ||||
| 
 | ||||
|     - name: build | ||||
|       run: docker build -t ${{ env.docker_image_name }}:${{ env.GitVersion_SemVer }} . | ||||
|          | ||||
|     - name: tag latest | ||||
|       run: docker tag ${{ env.docker_image_name }}:${{ env.GitVersion_SemVer }} ${{ env.docker_image_name }}:latest | ||||
| 
 | ||||
|     - name: push | ||||
|       run: docker push --all-tags ${{ env.docker_image_name }} | ||||
| 
 | ||||
|     - name: tag branch | ||||
|       run: | | ||||
|         git tag ${{ env.GitVersion_SemVer }} | ||||
|         git push origin ${{ env.GitVersion_SemVer }} | ||||
|          | ||||
|     - name: release | ||||
|       uses: softprops/action-gh-release@v1 | ||||
|       with: | ||||
|         token: ${{ secrets.GITHUB_TOKEN }} | ||||
|         tag_name: ${{ env.GitVersion_SemVer }} | ||||
|         generate_release_notes: true | ||||
							
								
								
									
										20
									
								
								.github/workflows/tag-stable-release.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.github/workflows/tag-stable-release.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| name: tag-stable-release | ||||
| on: | ||||
|   release: | ||||
|     types: [published] | ||||
| 
 | ||||
| jobs: | ||||
|   build-image: | ||||
|     runs-on: [self-hosted, Linux, k8s] | ||||
|     permissions: | ||||
|       packages: write | ||||
|     steps: | ||||
|       - name: login into registry | ||||
|         run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login https://ghcr.io -u $ --password-stdin | ||||
| 
 | ||||
|       - name: Tag latest | ||||
|         env: | ||||
|           docker_image_name: ghcr.io/data443/dim-search-web-ui | ||||
|         run: | | ||||
|           docker tag ${{ env.docker_image_name }}:${{ github.ref_name }} ${{ env.docker_image_name }}:stable | ||||
|           docker push --all-tags ${{ env.docker_image_name }} | ||||
							
								
								
									
										19
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| # See https://help.github.com/ignore-files/ for more about ignoring files. | ||||
| 
 | ||||
| # dependencies | ||||
| /node_modules | ||||
| 
 | ||||
| # misc | ||||
| .DS_Store | ||||
| 
 | ||||
| npm-debug.log* | ||||
| yarn-debug.log* | ||||
| yarn-error.log* | ||||
| 
 | ||||
| # Next.js | ||||
| /.next | ||||
| 
 | ||||
| #local env files | ||||
| .env*.local | ||||
| 
 | ||||
| /coverage | ||||
							
								
								
									
										57
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| # Install dependencies only when needed | ||||
| FROM node:16-alpine AS deps | ||||
| # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. | ||||
| RUN apk add --no-cache libc6-compat | ||||
| WORKDIR /app | ||||
| 
 | ||||
| # Install dependencies based on the preferred package manager | ||||
| COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ | ||||
| RUN \ | ||||
|   if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ | ||||
|   elif [ -f package-lock.json ]; then npm ci; \ | ||||
|   elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i; \ | ||||
|   else echo "Lockfile not found." && exit 1; \ | ||||
|   fi | ||||
| 
 | ||||
| 
 | ||||
| # Rebuild the source code only when needed | ||||
| FROM node:16-alpine AS builder | ||||
| WORKDIR /app | ||||
| COPY --from=deps /app/node_modules ./node_modules | ||||
| COPY . . | ||||
| 
 | ||||
| # Next.js collects completely anonymous telemetry data about general usage. | ||||
| # Learn more here: https://nextjs.org/telemetry | ||||
| # Uncomment the following line in case you want to disable telemetry during the build. | ||||
| ENV NEXT_TELEMETRY_DISABLED 1 | ||||
| 
 | ||||
| RUN yarn build | ||||
| 
 | ||||
| # If using npm comment out above and use below instead | ||||
| # RUN npm run build | ||||
| 
 | ||||
| # Production image, copy all the files and run next | ||||
| FROM node:16-alpine AS runner | ||||
| WORKDIR /app | ||||
| 
 | ||||
| ENV NODE_ENV production | ||||
| # Uncomment the following line in case you want to disable telemetry during runtime. | ||||
| ENV NEXT_TELEMETRY_DISABLED 1 | ||||
| 
 | ||||
| RUN addgroup --system --gid 1001 nodejs | ||||
| RUN adduser --system --uid 1001 nextjs | ||||
| 
 | ||||
| COPY --from=builder /app/public ./public | ||||
| 
 | ||||
| # Automatically leverage output traces to reduce image size | ||||
| # https://nextjs.org/docs/advanced-features/output-file-tracing | ||||
| COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ | ||||
| COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static | ||||
| 
 | ||||
| USER nextjs | ||||
| 
 | ||||
| EXPOSE 3000 | ||||
| 
 | ||||
| ENV PORT 3000 | ||||
| 
 | ||||
| CMD ["node", "server.js"] | ||||
							
								
								
									
										11
									
								
								GitVersion.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								GitVersion.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| assembly-versioning-scheme: MajorMinorPatch | ||||
| mode: ContinuousDelivery | ||||
| branches: {} | ||||
| ignore: | ||||
|   sha: [] | ||||
| merge-message-formats: {} | ||||
| commit-message-incrementing: Enabled | ||||
| major-version-bump-message: "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\\([\\w\\s-]*\\))?(!:|:.*\\n\\n((.+\\n)+\\n)?BREAKING CHANGE:\\s.+)" | ||||
| minor-version-bump-message: "^(feat)(\\([\\w\\s-]*\\))?:" | ||||
| patch-version-bump-message: "^(build|chore|ci|docs|fix|perf|refactor|revert|style|test)(\\([\\w\\s-]*\\))?:" | ||||
|    | ||||
							
								
								
									
										68
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| # Next.js and Auth0 Example | ||||
| 
 | ||||
| This example shows how you can use `@auth0/nextjs-auth` to easily add authentication support to your Next.js application. It tries to cover a few topics: | ||||
| 
 | ||||
| - Signing in | ||||
| - Signing out | ||||
| - Loading the user on the server side and adding it as part of SSR ([`pages/advanced/ssr-profile.tsx`](pages/advanced/ssr-profile.tsx)) | ||||
| - Loading the user on the client side and using fast/cached SSR pages ([`pages/index.tsx`](pages/index.tsx)) | ||||
| - Loading the user on the client side and checking authentication CSR pages ([`pages/profile.tsx`](pages/profile.tsx)) | ||||
| - Loading the user on the client side by accessing API (Serverless function) CSR pages ([`pages/advanced/api-profile.tsx`](pages/advanced/api-profile.tsx)) | ||||
| - Creates route handlers under the hood that perform different parts of the authentication flow ([`pages/auth/[...auth0].tsx`](pages/auth/[...auth0].tsx)) | ||||
| 
 | ||||
| Read more: [https://auth0.com/blog/ultimate-guide-nextjs-authentication-auth0/](https://auth0.com/blog/ultimate-guide-nextjs-authentication-auth0/) | ||||
| 
 | ||||
| ## How to use | ||||
| 
 | ||||
| Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example: | ||||
| 
 | ||||
| ```bash | ||||
| npx create-next-app --example auth0 auth0-app | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| yarn create next-app --example auth0 auth0-app | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| pnpm create next-app --example auth0 auth0-app | ||||
| ``` | ||||
| 
 | ||||
| ## Configuring Auth0 | ||||
| 
 | ||||
| 1. Go to the [Auth0 dashboard](https://manage.auth0.com/) and create a new application of type _Regular Web Applications_ and make sure to configure the following | ||||
| 2. Go to the settings page of the application | ||||
| 3. Configure the following settings: | ||||
| 
 | ||||
| - _Allowed Callback URLs_: Should be set to `http://localhost:3000/api/auth/callback` when testing locally or typically to `https://myapp.com/api/auth/callback` when deploying your application. | ||||
| - _Allowed Logout URLs_: Should be set to `http://localhost:3000/` when testing locally or typically to `https://myapp.com/` when deploying your application. | ||||
| 
 | ||||
| 4. Save the settings | ||||
| 
 | ||||
| ### Set up environment variables | ||||
| 
 | ||||
| To connect the app with Auth0, you'll need to add the settings from your Auth0 application as environment variables | ||||
| 
 | ||||
| Copy the `.env.local.example` file in this directory to `.env.local` (which will be ignored by Git): | ||||
| 
 | ||||
| ```bash | ||||
| cp .env.local.example .env.local | ||||
| ``` | ||||
| 
 | ||||
| Then, open `.env.local` and add the missing environment variables: | ||||
| 
 | ||||
| - `AUTH0_ISSUER_BASE_URL` - Can be found in the Auth0 dashboard under `settings`. (Should be prefixed with `https://`) | ||||
| - `AUTH0_CLIENT_ID` - Can be found in the Auth0 dashboard under `settings`. | ||||
| - `AUTH0_CLIENT_SECRET` - Can be found in the Auth0 dashboard under `settings`. | ||||
| - `AUTH0_BASE_URL` - The base url of the application. | ||||
| - `AUTH0_SECRET` - Has to be at least 32 characters. You can use [this generator](https://generate-secret.vercel.app/32) to generate a value. | ||||
| 
 | ||||
| ## Deploy on Vercel | ||||
| 
 | ||||
| You can deploy this app to the cloud with [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). | ||||
| 
 | ||||
| ### Deploy Your Local Project | ||||
| 
 | ||||
| To deploy your local project to Vercel, push it to GitHub/GitLab/Bitbucket and [import to Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example). | ||||
| 
 | ||||
| **Important**: When you import your project on Vercel, make sure to click on **Environment Variables** and set them to match your `.env.local` file. | ||||
							
								
								
									
										7
									
								
								additional.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								additional.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| export {}; | ||||
| 
 | ||||
| declare global { | ||||
|   interface Window { | ||||
|     __user: any; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										31
									
								
								components/artist.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								components/artist.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| import * as React from 'react'; | ||||
| import ImageListItem from '@mui/material/ImageListItem'; | ||||
| import ImageListItemBar from '@mui/material/ImageListItemBar'; | ||||
| import IconButton from '@mui/material/IconButton'; | ||||
| import InfoIcon from '@mui/icons-material/Info'; | ||||
| import Image from 'next/image'; | ||||
| 
 | ||||
| const Artist = ({artistId}) => { | ||||
|     return ( | ||||
|     <ImageListItem key="https://images.unsplash.com/photo-1551963831-b3b1ca40c98e"> | ||||
|     <img | ||||
|       srcSet={`https://images.unsplash.com/photo-1551963831-b3b1ca40c98e?w=248&fit=crop&auto=format&dpr=2 2x`} | ||||
|       src={`https://images.unsplash.com/photo-1551963831-b3b1ca40c98e?w=248&fit=crop&auto=format`} | ||||
|       alt={"Neroshi"} | ||||
|       loading="lazy" | ||||
|     /> | ||||
|     <ImageListItemBar | ||||
|       title={artistId} | ||||
|       subtitle={"0 Stars (0 Reviews)"} | ||||
|       actionIcon={ | ||||
|         <IconButton | ||||
|           sx={{ color: 'rgba(255, 255, 255, 0.54)' }} | ||||
|           aria-label={`info`} | ||||
|         > | ||||
|           <InfoIcon /> | ||||
|         </IconButton> | ||||
|       } | ||||
|     /> | ||||
|   </ImageListItem>) | ||||
| } | ||||
| export default Artist | ||||
							
								
								
									
										140
									
								
								components/header.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								components/header.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,140 @@ | ||||
| import * as React from 'react'; | ||||
| import { useUser } from "@auth0/nextjs-auth0/client"; | ||||
| import AppBar from '@mui/material/AppBar'; | ||||
| import Box from '@mui/material/Box'; | ||||
| import Toolbar from '@mui/material/Toolbar'; | ||||
| import IconButton from '@mui/material/IconButton'; | ||||
| import Typography from '@mui/material/Typography'; | ||||
| import Menu from '@mui/material/Menu'; | ||||
| import MenuIcon from '@mui/icons-material/Menu'; | ||||
| import Container from '@mui/material/Container'; | ||||
| import Avatar from '@mui/material/Avatar'; | ||||
| import Button from '@mui/material/Button'; | ||||
| import Tooltip from '@mui/material/Tooltip'; | ||||
| import MenuItem from '@mui/material/MenuItem'; | ||||
| import Badge from "@mui/material/Badge"; | ||||
| import NotificationsIcon from "@mui/icons-material/Notifications"; | ||||
| import AdbIcon from '@mui/icons-material/Adb'; | ||||
| import { Chip, Icon } from '@mui/material'; | ||||
| import { | ||||
|   NovuProvider, | ||||
|   PopoverNotificationCenter, | ||||
|   NotificationBell, | ||||
| } from '@novu/notification-center'; | ||||
| 
 | ||||
| 
 | ||||
| type HeaderProps = { | ||||
|   user?: any; | ||||
|   loading: boolean; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| const settings = ['Profile', 'Account', 'Dashboard', 'Logout']; | ||||
| 
 | ||||
| function ResponsiveAppBar() { | ||||
|   const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(null); | ||||
|   const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(null); | ||||
| 
 | ||||
|   const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => { | ||||
|     setAnchorElNav(event.currentTarget); | ||||
|   }; | ||||
|   const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => { | ||||
|     setAnchorElUser(event.currentTarget); | ||||
|   }; | ||||
| 
 | ||||
|   const handleCloseNavMenu = () => { | ||||
|     setAnchorElNav(null); | ||||
|   }; | ||||
| 
 | ||||
|   const handleCloseUserMenu = () => { | ||||
|     setAnchorElUser(null); | ||||
|   }; | ||||
| 
 | ||||
|   const { user, isLoading } = useUser(); | ||||
| 
 | ||||
|   return ( | ||||
|     <AppBar color="primary" position="static"> | ||||
|       <Container maxWidth="xl"> | ||||
|         <Toolbar disableGutters> | ||||
|               <Box sx={{ flex:1, textAlign:"center" }}> | ||||
|           <Typography | ||||
|             href="/" | ||||
|             variant="h6" | ||||
|             noWrap | ||||
|             color="secondary" | ||||
|             component="a" | ||||
|             sx={{ | ||||
|               mr: 2, | ||||
|               paddingLeft: '1rem', | ||||
|               display: { xs: 'none', md: 'flex' }, | ||||
|               fontFamily: 'monospace', | ||||
|               fontWeight: 700, | ||||
|               letterSpacing: '.3rem', | ||||
|               textDecoration: 'none', | ||||
|             }} | ||||
|           > | ||||
|             COMISSIONS.APP | ||||
|           </Typography> | ||||
|                 </Box> | ||||
| 
 | ||||
|           { | ||||
|             user ? ( | ||||
|               <> | ||||
|               <Box> | ||||
|                 <NovuProvider  subscriberId={'on-boarding-subscriber-id-123'} applicationIdentifier={'9SKjzgN_odAF'}> | ||||
|                   <PopoverNotificationCenter  colorScheme={'light'}> | ||||
|                     {({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />} | ||||
|                   </PopoverNotificationCenter> | ||||
|                 </NovuProvider> | ||||
|               </Box> | ||||
|                 <Box> | ||||
|                   <Chip | ||||
|                     onClick={handleOpenUserMenu} | ||||
|                     label={user.name} | ||||
|                     color="secondary" | ||||
|                     variant={'outlined'} | ||||
|                     style={{ marginLeft: '10px', minWidth: '5rem', maxWidth:'10rem' }} | ||||
|                   /> | ||||
|                   <Menu | ||||
|                     sx={{ mt: '45px' }} | ||||
|                     id="menu-appbar" | ||||
|                     anchorEl={anchorElUser} | ||||
|                     anchorOrigin={{ | ||||
|                       vertical: 'top', | ||||
|                       horizontal: 'right', | ||||
|                     }} | ||||
|                     keepMounted | ||||
|                     transformOrigin={{ | ||||
|                       vertical: 'top', | ||||
|                       horizontal: 'right', | ||||
|                     }} | ||||
|                     open={Boolean(anchorElUser)} | ||||
|                     onClose={handleCloseUserMenu} | ||||
|                   > | ||||
|                   <MenuItem key="logout" onClick={handleCloseUserMenu}> | ||||
|                     <Button color="primary" href="profile">Settings</Button> | ||||
|                   </MenuItem> | ||||
|                     <MenuItem key="logout" onClick={handleCloseUserMenu}> | ||||
|                       <Button color="error" href="/api/auth/logout">Logout</Button> | ||||
|                     </MenuItem> | ||||
|                   </Menu> | ||||
|                 </Box> | ||||
|               </> | ||||
|             ) : ( | ||||
|             <> | ||||
|             <Button key="login"  href='/api/auth/login' onClick={handleCloseNavMenu}  sx={{ my: 2, display: 'block', color:"white" }}> | ||||
|                 Login | ||||
|               </Button> | ||||
|               <Button key="signup"  href='/api/auth/login' onClick={handleCloseNavMenu}  sx={{ my: 2, display: 'block', color:"white" }}> | ||||
|                 Signup | ||||
|               </Button> | ||||
|             </> | ||||
|                | ||||
|           )} | ||||
| 
 | ||||
|         </Toolbar> | ||||
|       </Container> | ||||
|     </AppBar> | ||||
|   ); | ||||
| } | ||||
| export default ResponsiveAppBar; | ||||
							
								
								
									
										41
									
								
								components/layout.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								components/layout.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | ||||
| import Head from "next/head"; | ||||
| import Header from "./header"; | ||||
| 
 | ||||
| type LayoutProps = { | ||||
|   user?: any; | ||||
|   loading?: boolean; | ||||
|   children: React.ReactNode; | ||||
| }; | ||||
| 
 | ||||
| const Layout = ({ user, loading = false, children }: LayoutProps) => { | ||||
|   return ( | ||||
|     <> | ||||
|       <Head> | ||||
|         <title>Next.js with Auth0</title> | ||||
|       </Head> | ||||
| 
 | ||||
|       <Header user={user} loading={loading} /> | ||||
| 
 | ||||
|       <main> | ||||
|         <div className="container">{children}</div> | ||||
|       </main> | ||||
| 
 | ||||
|       <style jsx>{` | ||||
|         .container { | ||||
|           max-width: 42rem; | ||||
|           margin: 1.5rem auto; | ||||
|         } | ||||
|       `}</style>
 | ||||
|       <style jsx global>{` | ||||
|         body { | ||||
|           margin: 0; | ||||
|           color: #333; | ||||
|           font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, | ||||
|             Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; | ||||
|         } | ||||
|       `}</style>
 | ||||
|     </> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default Layout; | ||||
							
								
								
									
										9
									
								
								interfaces/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								interfaces/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| export type User = { | ||||
|   email: string; | ||||
|   email_verified: boolean; | ||||
|   name: string; | ||||
|   nickname: string; | ||||
|   picture: string; | ||||
|   sub: string; | ||||
|   updated_at: string; | ||||
| }; | ||||
							
								
								
									
										5
									
								
								next-env.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								next-env.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| /// <reference types="next" />
 | ||||
| /// <reference types="next/image-types/global" />
 | ||||
| 
 | ||||
| // NOTE: This file should not be edited
 | ||||
| // see https://nextjs.org/docs/basic-features/typescript for more information.
 | ||||
							
								
								
									
										2220
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										2220
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										27
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| { | ||||
|   "private": true, | ||||
|   "scripts": { | ||||
|     "dev": "next", | ||||
|     "build": "next build", | ||||
|     "start": "next start" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@auth0/nextjs-auth0": "^2.2.0", | ||||
|     "@emotion/react": "^11.11.3", | ||||
|     "@emotion/styled": "^11.11.0", | ||||
|     "@fontsource/roboto": "^5.0.8", | ||||
|     "@mui/icons-material": "^5.15.6", | ||||
|     "@mui/material": "^5.15.6", | ||||
|     "@novu/notification-center": "^0.22.0", | ||||
|     "next": "latest", | ||||
|     "openapi-typescript-fetch": "^1.1.3", | ||||
|     "react": "^18.2.0", | ||||
|     "react-dom": "^18.2.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/node": "^18.0.0", | ||||
|     "@types/react": "^18.0.14", | ||||
|     "@types/react-dom": "^18.0.5", | ||||
|     "typescript": "^4.7.4" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										38
									
								
								pages/_app.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								pages/_app.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| import { UserProvider } from "@auth0/nextjs-auth0/client"; | ||||
| import '@fontsource/roboto/300.css'; | ||||
| import '@fontsource/roboto/400.css'; | ||||
| import '@fontsource/roboto/500.css'; | ||||
| import '@fontsource/roboto/700.css'; | ||||
| import { createTheme } from '@mui/material/styles'; | ||||
| import { green, purple } from '@mui/material/colors'; | ||||
| import { ThemeProvider } from "@emotion/react"; | ||||
| 
 | ||||
| const theme = createTheme({ | ||||
|   palette: { | ||||
|     primary: { | ||||
|       main: '#1D3555', | ||||
|     }, | ||||
|     secondary: { | ||||
|       main: '#E5BEED' | ||||
|     }, | ||||
|     background: { | ||||
|       default: '#3D3E46', | ||||
|       paper: '#FAFAFF' | ||||
|     } | ||||
|   }, | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| export default function App({ Component, pageProps }) { | ||||
|   // optionally pass the 'user' prop from pages that require server-side
 | ||||
|   // rendering to prepopulate the 'useUser' hook.
 | ||||
|   const { user } = pageProps; | ||||
| 
 | ||||
|   return ( | ||||
|     <UserProvider user={user}> | ||||
|       <ThemeProvider theme={theme}> | ||||
|         <Component {...pageProps} /> | ||||
|       </ThemeProvider> | ||||
|     </UserProvider> | ||||
|   ); | ||||
| } | ||||
							
								
								
									
										24
									
								
								pages/about.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								pages/about.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| import { useUser } from "@auth0/nextjs-auth0/client"; | ||||
| import Layout from "../components/layout"; | ||||
| 
 | ||||
| const About = () => { | ||||
|   const { user, isLoading } = useUser(); | ||||
| 
 | ||||
|   return ( | ||||
|     <Layout user={user} loading={isLoading}> | ||||
|       <h1>About</h1> | ||||
|       <p> | ||||
|         This project shows different ways to display Profile info: using{" "} | ||||
|         <i>Client rendered</i>, <i>Server rendered</i>, and <i>API rendered</i> | ||||
|       </p> | ||||
|       <p> | ||||
|         Navigating between this page and <i>Home</i> is always pretty fast. | ||||
|         However, when you navigate to the <i>Server rendered profile</i> page it | ||||
|         takes more time because it uses SSR to fetch the user and then to | ||||
|         display it | ||||
|       </p> | ||||
|     </Layout> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default About; | ||||
							
								
								
									
										37
									
								
								pages/advanced/api-profile.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								pages/advanced/api-profile.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| import { useEffect, useState } from "react"; | ||||
| import { useUser } from "@auth0/nextjs-auth0/client"; | ||||
| import Layout from "../../components/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; | ||||
							
								
								
									
										26
									
								
								pages/advanced/ssr-profile.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								pages/advanced/ssr-profile.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| import { withPageAuthRequired } from "@auth0/nextjs-auth0"; | ||||
| import Layout from "../../components/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(); | ||||
							
								
								
									
										3
									
								
								pages/api/auth/[...auth0].tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pages/api/auth/[...auth0].tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| import { handleAuth } from "@auth0/nextjs-auth0"; | ||||
| 
 | ||||
| export default handleAuth(); | ||||
							
								
								
									
										20
									
								
								pages/api/protected-api.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								pages/api/protected-api.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| import { withApiAuthRequired, getSession } from "@auth0/nextjs-auth0"; | ||||
| 
 | ||||
| // Serverless function
 | ||||
| // Protected API, requests to '/api/protected' without a valid session cookie will fail
 | ||||
| 
 | ||||
| async function handle(req, res) { | ||||
|   const { user } = await getSession(req, res); | ||||
| 
 | ||||
|   try { | ||||
|     res.status(200).json({ | ||||
|       session: "true", | ||||
|       id: user.sub, | ||||
|       nickname: user.nickname, | ||||
|     }); | ||||
|   } catch (e) { | ||||
|     res.status(500).json({ error: "Unable to fetch", description: e }); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export default withApiAuthRequired(handle); | ||||
							
								
								
									
										199
									
								
								pages/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								pages/index.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,199 @@ | ||||
| import { useUser } from "@auth0/nextjs-auth0/client"; | ||||
| import Layout from "../components/layout"; | ||||
| import TextField from '@mui/material/TextField'; | ||||
| import Button from '@mui/material/Button'; | ||||
| import { Typography } from "@mui/material"; | ||||
| import Box from '@mui/material/Box'; | ||||
| import ButtonGroup from '@mui/material/ButtonGroup'; | ||||
| import styled from "@emotion/styled"; | ||||
| import IconButton from '@mui/material/IconButton'; | ||||
| import ImageList from '@mui/material/ImageList'; | ||||
| import ImageListItem from '@mui/material/ImageListItem'; | ||||
| import ImageListItemBar from '@mui/material/ImageListItemBar'; | ||||
| import ListSubheader from '@mui/material/ListSubheader'; | ||||
| import InfoIcon from '@mui/icons-material/Info'; | ||||
| import Chip from "@mui/material/Chip"; | ||||
| import { Fetcher } from "openapi-typescript-fetch"; | ||||
| import { paths } from "../types"; | ||||
| import Artist from "../components/artist"; | ||||
| 
 | ||||
| 
 | ||||
| const StyledTextField = styled(TextField)({ | ||||
|   "& .MuiInputLabel-root": { | ||||
|     right: 0, | ||||
|     textAlign: "center" | ||||
|   }, | ||||
|   "& .MuiInputLabel-shrink": { | ||||
|     margin: "0 auto", | ||||
|     position: "absolute", | ||||
|     right: "0", | ||||
|     left: "0", | ||||
|     top: "-3px", | ||||
|     width: "150px", // Need to give it a width so the positioning will work
 | ||||
|     background: "white" // Add a white background as below we remove the legend that had the background so text is not meshing with the border
 | ||||
|     // display: "none" //if you want to hide it completly
 | ||||
|   }, | ||||
|   "& .MuiOutlinedInput-root.Mui-focused": { | ||||
|     "& legend ": { | ||||
|       display: "none" | ||||
|     } | ||||
|   } | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| const Home = () => { | ||||
|   const { user, isLoading } = useUser(); | ||||
|   const fetcher = Fetcher.for<paths>() | ||||
|   fetcher.configure({ | ||||
|     baseUrl: 'https://localhost.7148', | ||||
|     init: { | ||||
|       headers: { | ||||
|    | ||||
|       }, | ||||
|     } | ||||
|   }) | ||||
| 
 | ||||
|   return ( | ||||
|     <Layout user={user} loading={isLoading}> | ||||
|       <> | ||||
|        | ||||
|         { user ? ( | ||||
|           <> | ||||
|         <Box sx={{ m: 1 }} /> | ||||
|           <ButtonGroup fullWidth variant="contained" aria-label="outlined primary button group"> | ||||
|             <Button color="primary" fullWidth>Your Orders</Button> | ||||
|             <Button color="secondary" fullWidth>Seller Dashboard</Button> | ||||
|           </ButtonGroup> | ||||
|           </> | ||||
|         ): ( | ||||
|           <Typography variant="h2" component="h2" textAlign="center">COMISSIONS.APP</Typography> | ||||
|         )}   | ||||
|         <Box sx={{ m: 2 }} /> | ||||
|         <StyledTextField    inputRef={input => input && input.focus()} sx={{input: {textAlign: "center"}}} fullWidth color="secondary" label="SEARCH ARTISTS" variant="outlined" /> | ||||
|         <Box sx={{ m: 4 }} /> | ||||
|         <div style={{ display: 'flex', justifyContent: 'center', marginTop: '10px' }}> | ||||
|         {chips.map((chip, index) => ( | ||||
|           <Chip | ||||
|             key={index} | ||||
|             label={chip.label} | ||||
|             color="primary" | ||||
|             variant={chip.outlined ? 'outlined' : 'default'} | ||||
|             onClick={() => console.log(`Clicked on ${chip.label}`)} | ||||
|             style={{ margin: '0 5px' }} | ||||
|           /> | ||||
|         ))} | ||||
|       </div> | ||||
| 
 | ||||
| 
 | ||||
|     <ImageList sx={{ flex:1 }}> | ||||
|       {itemData.map((item) => ( | ||||
|         <Artist artistId="1" /> | ||||
|       ))} | ||||
|     </ImageList> | ||||
|       </> | ||||
|     </Layout> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| // fast/cached SSR page
 | ||||
| export default Home; | ||||
| 
 | ||||
| 
 | ||||
| const chips = [ | ||||
|   { label: 'Category', outlined: true }, | ||||
|   { label: 'Category', outlined: false }, | ||||
|   { label: 'Category', outlined: true }, | ||||
|   { label: 'Category', outlined: false }, | ||||
|   { label: 'Category', outlined: true }, | ||||
|   { label: 'Category', outlined: false }, | ||||
|   { label: 'Category', outlined: true }, | ||||
|   { label: 'Category', outlined: false }, | ||||
| ]; | ||||
| 
 | ||||
| 
 | ||||
| const itemData = [ | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|     rows: 2, | ||||
|     cols: 2, | ||||
|     featured: true, | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|     rows: 2, | ||||
|     cols: 2, | ||||
|     featured: true, | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|     rows: 2, | ||||
|     cols: 2, | ||||
|     featured: true, | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|   }, | ||||
|   { | ||||
|     img: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e', | ||||
|     title: 'Neroshi', | ||||
|     author: '0 Stars (0 Reviews)', | ||||
|   }, | ||||
| ]; | ||||
							
								
								
									
										33
									
								
								pages/profile.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								pages/profile.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| import { withPageAuthRequired } from "@auth0/nextjs-auth0/client"; | ||||
| import Layout from "../components/layout"; | ||||
| import { User } from "../interfaces"; | ||||
| 
 | ||||
| type ProfileCardProps = { | ||||
|   user: User; | ||||
| }; | ||||
| 
 | ||||
| const ProfileCard = ({ user }: ProfileCardProps) => { | ||||
|   return ( | ||||
|     <> | ||||
|       <h1>Profile</h1> | ||||
| 
 | ||||
|       <div> | ||||
|         <h3>Profile (client rendered)</h3> | ||||
|         <img src={user.picture} alt="user picture" /> | ||||
|         <p>nickname: {user.nickname}</p> | ||||
|         <p>name: {user.name}</p> | ||||
|       </div> | ||||
|     </> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| const Profile = ({ user, isLoading }) => { | ||||
|   return ( | ||||
|     <Layout user={user} loading={isLoading}> | ||||
|       {isLoading ? <>Loading...</> : <ProfileCard user={user} />} | ||||
|     </Layout> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| // Protected route, checking user authentication client-side.(CSR)
 | ||||
| export default withPageAuthRequired(Profile); | ||||
							
								
								
									
										0
									
								
								pages/theme.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pages/theme.ts
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										2555
									
								
								swagger.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2555
									
								
								swagger.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										20
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|     "target": "es5", | ||||
|     "lib": ["dom", "dom.iterable", "esnext"], | ||||
|     "allowJs": true, | ||||
|     "skipLibCheck": true, | ||||
|     "strict": false, | ||||
|     "forceConsistentCasingInFileNames": true, | ||||
|     "noEmit": true, | ||||
|     "esModuleInterop": true, | ||||
|     "module": "esnext", | ||||
|     "moduleResolution": "node", | ||||
|     "resolveJsonModule": true, | ||||
|     "isolatedModules": true, | ||||
|     "jsx": "preserve", | ||||
|     "incremental": true | ||||
|   }, | ||||
|   "include": ["next-env.d.ts", "additional.d.ts", "**/*.ts", "**/*.tsx"], | ||||
|   "exclude": ["node_modules"] | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Damien Ostler
						Damien Ostler