├── src ├── App.css ├── vite-env.d.ts ├── types │ └── index.ts ├── store │ └── index.ts ├── index.css ├── main.tsx ├── App.tsx └── components │ └── ui │ ├── ViewNotes.tsx │ └── CreateNotes.tsx ├── postcss.config.js ├── tsconfig.json ├── vite.config.ts ├── tailwind.config.js ├── docker-compose.yml ├── Dockerfile ├── .gitignore ├── tsconfig.node.json ├── index.html ├── .eslintrc.cjs ├── tsconfig.app.json ├── package.json └── README.md /src/App.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | export interface noteType { 2 | title: string; 3 | description: string; 4 | } 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { noteType } from "../types"; 2 | 3 | export const notes: noteType[] = [ 4 | { 5 | title: "bac", 6 | description: "bbbbb", 7 | }, 8 | ]; 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.app.json" 6 | }, 7 | { 8 | "path": "./tsconfig.node.json" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | body { 6 | background-color: #1e252e; 7 | /* background-color: #0d1117; */ 8 | /* color: #fdf9d3; */ 9 | color: #d6eaff; 10 | } 11 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: [ 4 | "./index.html", 5 | "./src/**/*.{js,ts,jsx,tsx}", 6 | ], 7 | theme: { 8 | extend: {}, 9 | }, 10 | plugins: [], 11 | } 12 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | 3 | services: 4 | app: 5 | build: . 6 | container_name: note-app-docker 7 | ports: 8 | - "5173:5173" 9 | volumes: 10 | - .:/usr/src/app 11 | - /usr/src/app/node_modules 12 | command: npm run docker 13 | -------------------------------------------------------------------------------- /src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.tsx' 4 | import './index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20-alpine 2 | 3 | WORKDIR /usr/src/app 4 | 5 | COPY package*.json ./ 6 | 7 | RUN npm install 8 | 9 | COPY . . 10 | 11 | # need to remove when we use dev command 12 | # RUN npm run build 13 | 14 | EXPOSE 5173 15 | 16 | # CMD ["node", "dist/index.js"] 17 | CMD ["npm", "run", "docker"] -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 5 | "skipLibCheck": true, 6 | "module": "ESNext", 7 | "moduleResolution": "bundler", 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "noEmit": true 11 | }, 12 | "include": ["vite.config.ts"] 13 | } 14 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Note App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import "./App.css"; 2 | import CreateNotes from "./components/ui/CreateNotes"; 3 | 4 | function App() { 5 | return ( 6 |
7 |

8 | 9 | Note App 10 |

11 | 12 |
13 | ); 14 | } 15 | 16 | export default App; 17 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:@typescript-eslint/recommended', 7 | 'plugin:react-hooks/recommended', 8 | ], 9 | ignorePatterns: ['dist', '.eslintrc.cjs'], 10 | parser: '@typescript-eslint/parser', 11 | plugins: ['react-refresh'], 12 | rules: { 13 | 'react-refresh/only-export-components': [ 14 | 'warn', 15 | { allowConstantExport: true }, 16 | ], 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 5 | "target": "ES2020", 6 | "useDefineForClassFields": true, 7 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 8 | "module": "ESNext", 9 | "skipLibCheck": true, 10 | 11 | /* Bundler mode */ 12 | "moduleResolution": "bundler", 13 | "allowImportingTsExtensions": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "moduleDetection": "force", 17 | "noEmit": true, 18 | "jsx": "react-jsx", 19 | 20 | /* Linting */ 21 | "strict": true, 22 | "noUnusedLocals": true, 23 | "noUnusedParameters": true, 24 | "noFallthroughCasesInSwitch": true 25 | }, 26 | "include": ["src"] 27 | } 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "note-app", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "docker": "vite --host 0.0.0.0", 9 | "build": "tsc -b && vite build", 10 | "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 11 | "preview": "vite preview" 12 | }, 13 | "dependencies": { 14 | "react": "^18.3.1", 15 | "react-dom": "^18.3.1", 16 | "remixicon": "^4.3.0" 17 | }, 18 | "devDependencies": { 19 | "@types/react": "^18.3.3", 20 | "@types/react-dom": "^18.3.0", 21 | "@typescript-eslint/eslint-plugin": "^7.13.1", 22 | "@typescript-eslint/parser": "^7.13.1", 23 | "@vitejs/plugin-react": "^4.3.1", 24 | "autoprefixer": "^10.4.19", 25 | "eslint": "^8.57.0", 26 | "eslint-plugin-react-hooks": "^4.6.2", 27 | "eslint-plugin-react-refresh": "^0.4.7", 28 | "postcss": "^8.4.38", 29 | "tailwindcss": "^3.4.4", 30 | "typescript": "^5.2.2", 31 | "vite": "^5.3.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | export default { 18 | // other rules... 19 | parserOptions: { 20 | ecmaVersion: 'latest', 21 | sourceType: 'module', 22 | project: ['./tsconfig.json', './tsconfig.node.json'], 23 | tsconfigRootDir: __dirname, 24 | }, 25 | } 26 | ``` 27 | 28 | - Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` 29 | - Optionally add `plugin:@typescript-eslint/stylistic-type-checked` 30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list 31 | -------------------------------------------------------------------------------- /src/components/ui/ViewNotes.tsx: -------------------------------------------------------------------------------- 1 | import "remixicon/fonts/remixicon.css"; 2 | import { noteType } from "../../types"; 3 | 4 | const ViewNotes = ({ 5 | notes, 6 | onDeleteNote, 7 | }: { 8 | notes: noteType[]; 9 | onDeleteNote: (index: number) => void; 10 | }) => { 11 | return ( 12 |
13 | {/*

14 | View Notes 15 |

*/} 16 |
17 | {notes.map((e, index) => ( 18 |
19 |
20 |
21 |

{e.title}

22 |
{e.description}
23 |
24 |
25 | 31 |
32 |
33 | {/*
*/} 34 |
35 | ))} 36 |
37 |
38 | ); 39 | }; 40 | 41 | export default ViewNotes; 42 | -------------------------------------------------------------------------------- /src/components/ui/CreateNotes.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import ViewNotes from "./ViewNotes"; 3 | import { noteType } from "../../types"; 4 | 5 | const CreateNotes = () => { 6 | const [title, setTitle] = useState(""); 7 | const [description, setDescription] = useState(""); 8 | const [note, setNote] = useState([]); 9 | 10 | useEffect(() => { 11 | const storedNotes = JSON.parse(localStorage.getItem("notes") || "[]"); 12 | if (storedNotes) { 13 | setNote(storedNotes); 14 | } 15 | }, []); 16 | 17 | const handleCreateNote = () => { 18 | if (title.trim() === "" || description.trim() === "") { 19 | alert("Title and Description cannot be empty"); 20 | return; 21 | } 22 | 23 | const newNote = { title, description }; 24 | const updatedNotes: noteType[] = [...note, newNote]; 25 | setNote(updatedNotes); 26 | localStorage.setItem("notes", JSON.stringify(updatedNotes)); 27 | // alert("Note Created"); 28 | 29 | // Reset input fields 30 | setTitle(""); 31 | setDescription(""); 32 | }; 33 | 34 | const handleDeleteNote = (index: number) => { 35 | const updatedNotes = note.filter((_, i) => i !== index); 36 | setNote(updatedNotes); 37 | localStorage.setItem("notes", JSON.stringify(updatedNotes)); 38 | }; 39 | 40 | return ( 41 |
42 |
43 |
44 |

Add your title

45 | setTitle(e.target.value)} 50 | /> 51 |
52 |
53 |

Add your Description

54 | 59 |
60 | 66 |
67 | 68 | 69 |
70 | ); 71 | }; 72 | 73 | export default CreateNotes; 74 | --------------------------------------------------------------------------------