├── .env.local.example ├── .gitignore ├── README.md ├── TODOs.md ├── components ├── BMAC.js ├── Footer.js ├── Hero.js ├── HiddenEmail.js ├── LoginButtons.js ├── MDXComponents.js ├── NavBar.js ├── NextBreadcrumb.js ├── PageShell.js └── icons.js ├── firestore.rules ├── jsconfig.json ├── lib ├── auth.js ├── db-admin.js ├── db.js ├── firebase-admin.js ├── firebase.js └── middlewares.js ├── next.config.js ├── package.json ├── pages ├── _app.js ├── _document.js ├── account.js ├── dashboard.js ├── faq.mdx ├── index.js └── test.js ├── public ├── favicon.ico └── vercel.svg ├── styles └── theme.js ├── utils ├── fetcher.js └── logger.js └── yarn.lock /.env.local.example: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_FIREBASE_API_KEY = 2 | NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN = 3 | NEXT_PUBLIC_FIREBASE_PROJECT_ID = 4 | NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET = 5 | NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID = 6 | NEXT_PUBLIC_FIREBASE_APP_ID = 7 | 8 | FIREBASE_PRIVATE_KEY = 9 | FIREBASE_CLIENT_EMAIL = 10 | 11 | NEXT_PUBLIC_LOGFLARE_KEY = 12 | NEXT_PUBLIC_LOGFLARE_STREAM = 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Starter Template for Next.js with MDX, Firebase, Chakra UI, Logflare and Stripe 2 | 3 | --- 4 | 5 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 6 | 7 | ## Getting Started 8 | 9 | First, run the development server: 10 | 11 | ```bash 12 | npm run dev 13 | # or 14 | yarn dev 15 | ``` 16 | 17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 18 | 19 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file. 20 | 21 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`. 22 | 23 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. 24 | 25 | ## Learn More 26 | 27 | To learn more about Next.js, take a look at the following resources: 28 | 29 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 30 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 31 | 32 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 33 | 34 | ## Deploy on Vercel 35 | 36 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 37 | 38 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 39 | -------------------------------------------------------------------------------- /TODOs.md: -------------------------------------------------------------------------------- 1 | - [ ] refactor next-seo in \_app.js 2 | - [ ] clean up \_document.js 3 | - [ ] add a fuller mdx example 4 | - [ ] add stripe integration 5 | - [ ] handle multiple login provider merging 6 | - [ ] add example pages of a few different types 7 | -------------------------------------------------------------------------------- /components/BMAC.js: -------------------------------------------------------------------------------- 1 | const BMAC = () => { 2 | return ( 3 | <> 4 | 5 | Buy Me A Coffee 10 | 11 | 24 | 25 | ); 26 | }; 27 | 28 | export default BMAC; 29 | -------------------------------------------------------------------------------- /components/Footer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import NextLink from 'next/link'; 3 | import { Link, Flex, HStack } from '@chakra-ui/react'; 4 | 5 | const FooterLink = ({ href, children }) => { 6 | return ( 7 | 8 | 9 | {children} 10 | 11 | 12 | ); 13 | }; 14 | 15 | const Footer = () => { 16 | return ( 17 | 18 | Privacy 19 | Terms 20 | FAQ 21 | Home 22 | 23 | ); 24 | }; 25 | 26 | export default Footer; 27 | -------------------------------------------------------------------------------- /components/Hero.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import NextLink from 'next/link'; 3 | import { 4 | Box, 5 | Button, 6 | Avatar, 7 | HStack, 8 | Flex, 9 | Link, 10 | Icon, 11 | SkeletonCircle, 12 | Heading, 13 | Text, 14 | } from '@chakra-ui/react'; 15 | import LoginButtons from '@/components/LoginButtons'; 16 | 17 | const Hero = () => { 18 | return ( 19 | 26 | 27 | 28 | 29 | Here are some{' '} 30 | 31 | 37 | important stuff 38 | 39 | 40 | {' '} 41 | about this website. 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | ); 50 | }; 51 | 52 | export default Hero; 53 | -------------------------------------------------------------------------------- /components/HiddenEmail.js: -------------------------------------------------------------------------------- 1 | export default function HiddenEmail() { 2 | const clickHander = (e) => { 3 | window.location.href = 4 | 'mailto:' + 5 | e.target.dataset.name + 6 | '@' + 7 | e.target.dataset.domain + 8 | '.' + 9 | e.target.dataset.tld; 10 | return false; 11 | }; 12 | return ( 13 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /components/LoginButtons.js: -------------------------------------------------------------------------------- 1 | import { Button, Flex } from '@chakra-ui/react'; 2 | 3 | import { useAuth } from '@/lib/auth'; 4 | import { FcGoogle } from 'react-icons/fc'; 5 | import { FaTwitter } from 'react-icons/fa'; 6 | 7 | const LoginButtons = () => { 8 | const auth = useAuth(); 9 | 10 | return ( 11 | 12 | {/* */} 24 | 35 | 36 | ); 37 | }; 38 | 39 | export default LoginButtons; 40 | -------------------------------------------------------------------------------- /components/MDXComponents.js: -------------------------------------------------------------------------------- 1 | import NextLink from 'next/link'; 2 | import { Link } from '@chakra-ui/react'; 3 | import Image from 'next/image'; 4 | import { Box, Code, Heading } from '@chakra-ui/react'; 5 | 6 | const CustomLink = (props) => { 7 | const href = props.href; 8 | const isInternalLink = href && (href.startsWith('/') || href.startsWith('#')); 9 | 10 | if (isInternalLink) { 11 | return ( 12 | 13 | 14 | 15 | ); 16 | } 17 | 18 | return ; 19 | }; 20 | 21 | const MDXComponents = { 22 | Image, 23 | a: CustomLink, 24 | pre: (props) =>
, 25 | // code: CodeBlock, 26 | inlineCode: Code, 27 | h1: (props) => , 28 | h2: (props) => , 29 | h3: (props) => , 30 | p: (props) => , 31 | }; 32 | 33 | export default MDXComponents; 34 | -------------------------------------------------------------------------------- /components/NavBar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import NextLink from 'next/link'; 3 | import Router from 'next/router'; 4 | import { Logo } from './icons'; 5 | import { 6 | Box, 7 | Button, 8 | Heading, 9 | Avatar, 10 | HStack, 11 | Flex, 12 | Link, 13 | Icon, 14 | SkeletonCircle, 15 | useMediaQuery, 16 | } from '@chakra-ui/react'; 17 | 18 | import { useAuth } from '@/lib/auth'; 19 | 20 | const WrappedLink = ({ href, children }) => { 21 | return ( 22 | 23 | {children} 24 | 25 | ); 26 | }; 27 | 28 | const Navbar = (props) => { 29 | const { user } = useAuth(); 30 | const innerWidth = props.innerWidth || '1040px'; 31 | const [largeScreen] = useMediaQuery('(min-width: 700px)'); 32 | 33 | return ( 34 | 43 | 52 | 53 | 54 | 55 | 56 | {largeScreen ? ( 57 | 58 | 59 | Site Name 60 | 61 | 62 | ) : null} 63 | 64 | 65 | 66 | FAQ 67 | 68 | {user ? ( 69 | <> 70 | 77 | 78 | 79 | 80 | 81 | ) : null} 82 | 83 | 84 | 85 | ); 86 | }; 87 | 88 | export default Navbar; 89 | -------------------------------------------------------------------------------- /components/NextBreadcrumb.js: -------------------------------------------------------------------------------- 1 | import { Breadcrumb, BreadcrumbItem, BreadcrumbLink } from '@chakra-ui/react'; 2 | import NextLink from 'next/link'; 3 | 4 | const NextBreadcrumb = ({ pagePath, pageName }) => { 5 | return ( 6 | 7 | 8 | 9 | Home 10 | 11 | 12 | 13 | 14 | {pageName} 15 | 16 | 17 | 18 | ); 19 | }; 20 | 21 | export default NextBreadcrumb; 22 | -------------------------------------------------------------------------------- /components/PageShell.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import NextLink from 'next/link'; 3 | import { Box, Button, Flex, Link, Avatar, Icon } from '@chakra-ui/react'; 4 | 5 | import Footer from './Footer'; 6 | import Navbar from './NavBar'; 7 | 8 | const inner = { 9 | m: '0 auto', 10 | maxW: '1040px', 11 | width: '100%', 12 | flexGrow: 1, 13 | }; 14 | 15 | const DashboardShell = ({ children }) => { 16 | return ( 17 | 18 | 19 | 20 | {children} 21 | 22 |