├── .eslintrc.json ├── .gitignore ├── README.md ├── firebase └── clientApp.ts ├── next-env.d.ts ├── next.config.js ├── package-lock.json ├── package.json ├── pages ├── _app.tsx ├── add-todo.tsx ├── api │ └── hello.ts └── index.tsx ├── public ├── favicon.ico └── vercel.svg ├── styles ├── Home.module.css └── globals.css └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.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 | 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). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | 15 | You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file. 16 | 17 | [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.ts`. 18 | 19 | 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. 20 | 21 | ## Learn More 22 | 23 | To learn more about Next.js, take a look at the following resources: 24 | 25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 27 | 28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 29 | 30 | ## Deploy on Vercel 31 | 32 | 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. 33 | 34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 35 | -------------------------------------------------------------------------------- /firebase/clientApp.ts: -------------------------------------------------------------------------------- 1 | import {initializeApp} from "firebase/app"; 2 | import {getFirestore} from "firebase/firestore"; 3 | 4 | initializeApp({ 5 | apiKey:process.env.NEXT_PUBLIC_FIREBASE_API_KEY, 6 | authDomain:process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, 7 | projectId:process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, 8 | storageBucket:process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, 9 | messagingSenderId:process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, 10 | appId:process.env.NEXT_PUBLIC_FIREBASE_APP_ID, 11 | measurementId:process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID 12 | }); 13 | 14 | const firestore = getFirestore(); 15 | 16 | export {firestore}; -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | 5 | // NOTE: This file should not be edited 6 | // see https://nextjs.org/docs/basic-features/typescript for more information. 7 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | module.exports = { 3 | reactStrictMode: true, 4 | } 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todos-app-1", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "firebase": "^9.1.2", 13 | "next": "11.1.2", 14 | "react": "17.0.2", 15 | "react-dom": "17.0.2" 16 | }, 17 | "devDependencies": { 18 | "@types/react": "17.0.27", 19 | "eslint": "8.0.0", 20 | "eslint-config-next": "11.1.2", 21 | "typescript": "4.4.3" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css' 2 | import type { AppProps } from 'next/app' 3 | 4 | function MyApp({ Component, pageProps }: AppProps) { 5 | return 6 | } 7 | export default MyApp 8 | -------------------------------------------------------------------------------- /pages/add-todo.tsx: -------------------------------------------------------------------------------- 1 | import { doc } from '@firebase/firestore'; 2 | import { setDoc } from 'firebase/firestore'; 3 | import type { NextPage } from 'next' 4 | import Head from "next/head"; 5 | import { useState } from 'react'; 6 | import { firestore } from '../firebase/clientApp'; 7 | import styles from '../styles/Home.module.css' 8 | 9 | const AddTodo:NextPage = () => { 10 | 11 | const [title,setTitle] = useState(""); // title 12 | const [description,setDescription] = useState("");// description 13 | const [error,setError] = useState("");// error 14 | const [message,setMessage] = useState("");// message 15 | 16 | const handleSubmit = (e: { preventDefault: () => void; }) => { 17 | e.preventDefault(); // avoid default behaviour 18 | 19 | if(!title || !description){ // check for any null value 20 | return setError("All fields are required"); 21 | } 22 | addTodo(); 23 | } 24 | 25 | const addTodo = async () => { 26 | // get the current timestamp 27 | const timestamp:string = Date.now().toString(); 28 | // create a pointer to our document 29 | const _todo = doc(firestore,`todos/${timestamp}`); 30 | // structure the todo data 31 | const todoData = { 32 | title, 33 | description, 34 | done:false 35 | }; 36 | 37 | try{ 38 | //add the document 39 | await setDoc(_todo,todoData); 40 | //show a success message 41 | setMessage("Todo added successfully"); 42 | //reset fields 43 | setTitle(""); 44 | setDescription(""); 45 | }catch(error){ 46 | //show an error message 47 | setError("An error occurred while adding todo"); 48 | } 49 | }; 50 | 51 | return ( 52 |
53 | 54 | Add todo 55 | 56 | 57 | 58 |
59 | 60 |

61 | Add todo 62 |

63 | 64 |
65 | 66 | { 67 | error ? ( 68 |
69 |

{error}

70 |
71 | ) : null 72 | } 73 | 74 | { 75 | message ? ( 76 |
77 |

78 | {message}. Proceed to Home 79 |

80 |
81 | ) : null 82 | } 83 | 84 |
85 | 86 | setTitle(e.target.value)} 89 | value={title} 90 | /> 91 |
92 | 93 |
94 | 95 |