├── .gitignore ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt ├── src ├── assets │ ├── fonts │ │ └── .gitkeep │ └── images │ │ └── .gitkeep ├── components │ ├── atoms │ │ ├── button │ │ │ └── button.tsx │ │ ├── form │ │ │ └── form.tsx │ │ ├── input │ │ │ └── input.tsx │ │ └── label │ │ │ └── label.tsx │ ├── molecules │ │ └── form-input │ │ │ └── form-input.tsx │ ├── organisms │ │ └── login-form │ │ │ └── login-form.tsx │ └── templates │ │ ├── auth-template │ │ └── auth-template.tsx │ │ └── layouts │ │ └── .gitkeep ├── index.tsx ├── lib │ ├── constants │ │ └── .gitkeep │ ├── helpers │ │ └── .gitkeep │ ├── hooks │ │ └── .gitkeep │ ├── store │ │ └── .gitkeep │ └── types │ │ └── .gitkeep ├── pages │ └── App.tsx ├── react-app-env.d.ts ├── reportWebVitals.ts ├── routes │ └── .gitkeep ├── services │ ├── products │ │ ├── api.ts │ │ ├── keys.ts │ │ ├── mutations.ts │ │ ├── queries.ts │ │ └── types.ts │ └── user │ │ ├── api.ts │ │ ├── keys.ts │ │ ├── mutations.ts │ │ ├── queries.ts │ │ └── types.ts ├── setupTests.ts └── styles │ └── .gitkeep └── tsconfig.json /.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 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2025 Shpend Rrustemi 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | src/ 3 | ├── assets/ # Static assets (images, fonts) 4 | │ ├── fonts/ 5 | │ ├── images/ 6 | │ 7 | ├── components/ # UI Components (Atomic Design) 8 | │ ├── atoms/ # Smallest reusable components (Button, Input, Label) 9 | │ ├── molecules/ # Grouped atoms forming functional components 10 | │ ├── organisms/ # Complex UI structures combining molecules 11 | │ ├── templates/ # Page layouts (AuthLayout, DashboardLayout) 12 | │ 13 | ├── lib/ # Business logic and utilities 14 | │ ├── constants/ # Global constants 15 | │ ├── helpers/ # Utility functions 16 | │ ├── hooks/ # Custom reusable hooks 17 | │ ├── store/ # State management (Redux/Zustand) 18 | │ ├── types/types.ts # Shared TypeScript types and interfaces 19 | │ 20 | ├── pages/ # Page components (LoginPage, DashboardPage) 21 | │ ├── App.tsx # Main app entry point 22 | ├── routes/ # Centralized app routing 23 | │ ├── routes.tsx 24 | │ 25 | ├── services/ # API services (fetching data) 26 | │ ├── products/ # Product API services 27 | │ │ ├── queries.ts # React Query fetching 28 | | | ├── keys.ts # Query keys 29 | │ │ ├── mutations.ts # React Query mutations 30 | │ │ ├── api.ts # API functions 31 | │ 32 | ├── styles/ # Global styles (CSS Modules, Tailwind, etc.) 33 | │ ├── globals.css 34 | │ 35 | ├── index.tsx # React root file 36 | ├── .env.local # Environment variables 37 | ├── .gitignore 38 | ├── package.json 39 | 40 | ``` 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-architecture", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/dom": "^10.4.0", 7 | "@testing-library/jest-dom": "^6.6.3", 8 | "@testing-library/react": "^16.2.0", 9 | "@testing-library/user-event": "^13.5.0", 10 | "@types/jest": "^27.5.2", 11 | "@types/node": "^16.18.126", 12 | "@types/react": "^19.0.12", 13 | "@types/react-dom": "^19.0.4", 14 | "react": "^19.0.0", 15 | "react-dom": "^19.0.0", 16 | "react-scripts": "5.0.1", 17 | "typescript": "^4.9.5", 18 | "web-vitals": "^2.1.4" 19 | }, 20 | "scripts": { 21 | "start": "react-scripts start", 22 | "build": "react-scripts build", 23 | "test": "react-scripts test", 24 | "eject": "react-scripts eject" 25 | }, 26 | "eslintConfig": { 27 | "extends": [ 28 | "react-app", 29 | "react-app/jest" 30 | ] 31 | }, 32 | "browserslist": { 33 | "production": [ 34 | ">0.2%", 35 | "not dead", 36 | "not op_mini all" 37 | ], 38 | "development": [ 39 | "last 1 chrome version", 40 | "last 1 firefox version", 41 | "last 1 safari version" 42 | ] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/assets/fonts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/assets/fonts/.gitkeep -------------------------------------------------------------------------------- /src/assets/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/assets/images/.gitkeep -------------------------------------------------------------------------------- /src/components/atoms/button/button.tsx: -------------------------------------------------------------------------------- 1 | import { ButtonHTMLAttributes, FC } from "react"; 2 | 3 | interface IButtonProps extends ButtonHTMLAttributes { 4 | label: string; 5 | } 6 | 7 | const Button: FC = ({ label, ...rest }) => { 8 | return ; 9 | }; 10 | 11 | export default Button; 12 | -------------------------------------------------------------------------------- /src/components/atoms/form/form.tsx: -------------------------------------------------------------------------------- 1 | import React, { FormHTMLAttributes, ReactNode } from "react"; 2 | 3 | interface IFormProps extends FormHTMLAttributes { 4 | children: ReactNode; 5 | } 6 | 7 | const Form: React.FC = ({ children, ...rest }) => { 8 | return
{children}
; 9 | }; 10 | 11 | export default Form; 12 | -------------------------------------------------------------------------------- /src/components/atoms/input/input.tsx: -------------------------------------------------------------------------------- 1 | import React, { InputHTMLAttributes } from "react"; 2 | 3 | interface IInputProps extends InputHTMLAttributes {} 4 | 5 | const Input: React.FC = ({ ...rest }) => { 6 | return ; 7 | }; 8 | 9 | export default Input; 10 | -------------------------------------------------------------------------------- /src/components/atoms/label/label.tsx: -------------------------------------------------------------------------------- 1 | import React, { LabelHTMLAttributes } from "react"; 2 | 3 | interface ILabelProps extends LabelHTMLAttributes { 4 | text: string; 5 | htmlFor: string; 6 | } 7 | 8 | const Label: React.FC = ({ text, ...rest }) => { 9 | return ; 10 | }; 11 | 12 | export default Label; 13 | -------------------------------------------------------------------------------- /src/components/molecules/form-input/form-input.tsx: -------------------------------------------------------------------------------- 1 | import Button from "components/atoms/button/button"; 2 | import Form from "components/atoms/form/form"; 3 | import Input from "components/atoms/input/input"; 4 | import Label from "components/atoms/label/label"; 5 | import React, { FormEvent, useState } from "react"; 6 | 7 | interface FormInputProps { 8 | label: string; 9 | inputType?: string; 10 | placeholder?: string; 11 | buttonText: string; 12 | onSubmit: (value: string) => void; 13 | } 14 | 15 | const FormInput: React.FC = ({ 16 | label, 17 | inputType = "text", 18 | placeholder, 19 | buttonText, 20 | onSubmit, 21 | }) => { 22 | const [value, setValue] = useState(""); 23 | 24 | const handleSubmit = (event: FormEvent) => { 25 | event.preventDefault(); 26 | onSubmit(value); 27 | }; 28 | 29 | return ( 30 |
31 |