From e0aea5745ba156ff559078d19cfcda305ad92e83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Beserra=20de=20Souza?= Date: Sat, 11 Nov 2023 12:18:33 -0300 Subject: [PATCH 01/20] feat(material-ui-nextjs): template configuration --- .gitignore | 36 + jsconfig.json | 7 + next.config.js | 22 + package.json | 23 + src/app/favicon.ico | Bin 0 -> 99166 bytes src/app/layout.js | 42 + src/app/page.js | 45 + src/components/MediaCard.js | 37 + src/components/ThemeRegistry/EmotionCache.js | 79 + src/components/ThemeRegistry/ThemeRegistry.js | 18 + src/components/ThemeRegistry/theme.js | 30 + yarn.lock | 2571 +++++++++++++++++ 12 files changed, 2910 insertions(+) create mode 100644 .gitignore create mode 100644 jsconfig.json create mode 100644 next.config.js create mode 100644 package.json create mode 100644 src/app/favicon.ico create mode 100644 src/app/layout.js create mode 100644 src/app/page.js create mode 100644 src/components/MediaCard.js create mode 100644 src/components/ThemeRegistry/EmotionCache.js create mode 100644 src/components/ThemeRegistry/ThemeRegistry.js create mode 100644 src/components/ThemeRegistry/theme.js create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b1913e --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..b8d6842 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..bdb623c --- /dev/null +++ b/next.config.js @@ -0,0 +1,22 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + reactStrictMode: true, + swcMinify: true, + modularizeImports: { + '@mui/icons-material': { + transform: '@mui/icons-material/{{member}}', + }, + }, + images: { + remotePatterns: [ + { + protocol: 'https', + hostname: 'source.unsplash.com', + port: '', + pathname: '/random', + }, + ], + }, +}; + +module.exports = nextConfig; diff --git a/package.json b/package.json new file mode 100644 index 0000000..e6764af --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "desafio-frontend", + "version": "0.0.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@emotion/cache": "^11.11.0", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.14.16", + "@mui/material": "^5.14.17", + "eslint": "^8.41.0", + "eslint-config-next": "^13.4.4", + "next": "^13.4.4", + "react": "^18.2.0", + "react-dom": "^18.2.0" + } +} diff --git a/src/app/favicon.ico b/src/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7bb2bd597d64c76023f52414e19347c6e2b841b5 GIT binary patch literal 99166 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 + + + {/* + + + + Next.js App Router + + + */} + + {children} + + + + + ); +} diff --git a/src/app/page.js b/src/app/page.js new file mode 100644 index 0000000..509f236 --- /dev/null +++ b/src/app/page.js @@ -0,0 +1,45 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Grid from '@mui/material/Unstable_Grid2'; +import Alert from '@mui/material/Alert'; +import AlertTitle from '@mui/material/AlertTitle'; +import MediaCard from '@/components/MediaCard'; + +export default function HomePage() { + return ( + +
+ + Hello 👋 + This app uses the Next.js App Router and Material UI v5. + + + + + + + + + + + + + + + +
+
+ ); +} diff --git a/src/components/MediaCard.js b/src/components/MediaCard.js new file mode 100644 index 0000000..e06e63b --- /dev/null +++ b/src/components/MediaCard.js @@ -0,0 +1,37 @@ +import * as React from 'react'; +import Image from 'next/image'; +import Card from '@mui/material/Card'; +import CardActions from '@mui/material/CardActions'; +import CardContent from '@mui/material/CardContent'; +import Button from '@mui/material/Button'; +import Typography from '@mui/material/Typography'; + +export default function MediaCard({ heading, text }) { + return ( + + Random image + + + {heading} + + + {text} + + + + + + + + ); +} diff --git a/src/components/ThemeRegistry/EmotionCache.js b/src/components/ThemeRegistry/EmotionCache.js new file mode 100644 index 0000000..d0b6345 --- /dev/null +++ b/src/components/ThemeRegistry/EmotionCache.js @@ -0,0 +1,79 @@ +'use client'; +import * as React from 'react'; +import createCache from '@emotion/cache'; +import { useServerInsertedHTML } from 'next/navigation'; +import { CacheProvider as DefaultCacheProvider } from '@emotion/react'; + +// Adapted from https://github.com/garronej/tss-react/blob/main/src/next/appDir.tsx +export default function NextAppDirEmotionCacheProvider(props) { + const { options, CacheProvider = DefaultCacheProvider, children } = props; + + const [registry] = React.useState(() => { + const cache = createCache(options); + cache.compat = true; + const prevInsert = cache.insert; + let inserted = []; + cache.insert = (...args) => { + const [selector, serialized] = args; + if (cache.inserted[serialized.name] === undefined) { + inserted.push({ + name: serialized.name, + isGlobal: !selector, + }); + } + return prevInsert(...args); + }; + const flush = () => { + const prevInserted = inserted; + inserted = []; + return prevInserted; + }; + return { cache, flush }; + }); + + useServerInsertedHTML(() => { + const inserted = registry.flush(); + if (inserted.length === 0) { + return null; + } + let styles = ''; + let dataEmotionAttribute = registry.cache.key; + + const globals = []; + + inserted.forEach(({ name, isGlobal }) => { + const style = registry.cache.inserted[name]; + + if (typeof style !== 'boolean') { + if (isGlobal) { + globals.push({ name, style }); + } else { + styles += style; + dataEmotionAttribute += ` ${name}`; + } + } + }); + + return ( + + {globals.map(({ name, style }) => ( +