├── .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 ;
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 |
43 | );
44 | };
45 |
46 | export default FormInput;
47 |
--------------------------------------------------------------------------------
/src/components/organisms/login-form/login-form.tsx:
--------------------------------------------------------------------------------
1 | import FormInput from "components/molecules/form-input/form-input";
2 | import React from "react";
3 |
4 | const LoginForm = () => {
5 | const handleLogin = (value: string) => {
6 | console.log("Logging in with:", value);
7 | };
8 |
9 | return (
10 |
11 |
Login
12 |
18 |
25 |
26 | );
27 | };
28 |
29 | export default LoginForm;
30 |
--------------------------------------------------------------------------------
/src/components/templates/auth-template/auth-template.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | interface AuthTemplateProps {
4 | title: string;
5 | children: React.ReactNode;
6 | }
7 |
8 | const AuthTemplate: FC = ({ title, children }) => {
9 | return (
10 |
19 |
{title}
20 |
29 | {children}
30 |
31 |
32 | );
33 | };
34 |
35 | export default AuthTemplate;
36 |
--------------------------------------------------------------------------------
/src/components/templates/layouts/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/components/templates/layouts/.gitkeep
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import reportWebVitals from "./reportWebVitals";
4 | import App from "pages/App";
5 |
6 | const root = ReactDOM.createRoot(
7 | document.getElementById("root") as HTMLElement
8 | );
9 | root.render(
10 |
11 |
12 |
13 | );
14 |
15 | // If you want to start measuring performance in your app, pass a function
16 | // to log results (for example: reportWebVitals(console.log))
17 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
18 | reportWebVitals();
19 |
--------------------------------------------------------------------------------
/src/lib/constants/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/lib/constants/.gitkeep
--------------------------------------------------------------------------------
/src/lib/helpers/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/lib/helpers/.gitkeep
--------------------------------------------------------------------------------
/src/lib/hooks/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/lib/hooks/.gitkeep
--------------------------------------------------------------------------------
/src/lib/store/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/lib/store/.gitkeep
--------------------------------------------------------------------------------
/src/lib/types/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/lib/types/.gitkeep
--------------------------------------------------------------------------------
/src/pages/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import logo from './logo.svg';
3 | import './App.css';
4 |
5 | function App() {
6 | return (
7 |
23 | );
24 | }
25 |
26 | export default App;
27 |
--------------------------------------------------------------------------------
/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/src/routes/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/routes/.gitkeep
--------------------------------------------------------------------------------
/src/services/products/api.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/services/products/api.ts
--------------------------------------------------------------------------------
/src/services/products/keys.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/services/products/keys.ts
--------------------------------------------------------------------------------
/src/services/products/mutations.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/services/products/mutations.ts
--------------------------------------------------------------------------------
/src/services/products/queries.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/services/products/queries.ts
--------------------------------------------------------------------------------
/src/services/products/types.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/services/products/types.ts
--------------------------------------------------------------------------------
/src/services/user/api.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/services/user/api.ts
--------------------------------------------------------------------------------
/src/services/user/keys.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/services/user/keys.ts
--------------------------------------------------------------------------------
/src/services/user/mutations.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/services/user/mutations.ts
--------------------------------------------------------------------------------
/src/services/user/queries.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/services/user/queries.ts
--------------------------------------------------------------------------------
/src/services/user/types.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/services/user/types.ts
--------------------------------------------------------------------------------
/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/src/styles/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shpendrr/react-app-structure/ba37c8218eb625ff885c42c89636564b1caa42d1/src/styles/.gitkeep
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "react-jsx",
22 | "baseUrl": "src"
23 | },
24 | "include": [
25 | "src"
26 | ]
27 | }
--------------------------------------------------------------------------------