react-repos 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -9
- package/repos/task-common/README.md +63 -0
- package/repos/task-common/backend/.env.example +3 -0
- package/repos/task-common/backend/app.js +16 -0
- package/repos/task-common/backend/config/db.js +11 -0
- package/repos/task-common/backend/controllers/itemController.js +51 -0
- package/repos/task-common/backend/data/items.json +5 -0
- package/repos/task-common/backend/middleware/errorHandler.js +7 -0
- package/repos/task-common/backend/middleware/notFound.js +3 -0
- package/repos/task-common/backend/models/Item.js +16 -0
- package/repos/task-common/backend/package.json +22 -0
- package/repos/task-common/backend/pnpm-lock.yaml +970 -0
- package/repos/task-common/backend/routes/itemRoutes.js +9 -0
- package/repos/task-common/backend/scripts/seed.js +22 -0
- package/repos/task-common/backend/server.js +12 -0
- package/repos/task-common/backend/test/buildQuery.test.js +16 -0
- package/repos/task-common/backend/utils/buildQuery.js +15 -0
- package/repos/task-common/frontend/.env.example +2 -0
- package/repos/task-common/frontend/package.json +27 -0
- package/repos/task-common/frontend/pnpm-lock.yaml +12209 -0
- package/repos/task-common/frontend/public/index.html +14 -0
- package/repos/task-common/frontend/src/App.js +28 -0
- package/repos/task-common/frontend/src/App.test.js +14 -0
- package/repos/task-common/frontend/src/api/httpClient.js +14 -0
- package/repos/task-common/frontend/src/api/itemService.js +9 -0
- package/repos/task-common/frontend/src/components/common/Badge.js +12 -0
- package/repos/task-common/frontend/src/components/common/ConfirmDialog.js +8 -0
- package/repos/task-common/frontend/src/components/common/DataTable.js +9 -0
- package/repos/task-common/frontend/src/components/common/EmptyState.js +6 -0
- package/repos/task-common/frontend/src/components/common/ErrorAlert.js +6 -0
- package/repos/task-common/frontend/src/components/common/FilterBar.js +8 -0
- package/repos/task-common/frontend/src/components/common/LoadingState.js +5 -0
- package/repos/task-common/frontend/src/components/common/Modal.js +8 -0
- package/repos/task-common/frontend/src/components/common/PageHeader.js +8 -0
- package/repos/task-common/frontend/src/components/common/Pagination.js +10 -0
- package/repos/task-common/frontend/src/components/common/ProgressBar.js +9 -0
- package/repos/task-common/frontend/src/components/common/StatCard.js +8 -0
- package/repos/task-common/frontend/src/components/items/ItemCard.js +10 -0
- package/repos/task-common/frontend/src/components/items/ItemForm.js +18 -0
- package/repos/task-common/frontend/src/components/layout/AppLayout.js +11 -0
- package/repos/task-common/frontend/src/components/layout/Sidebar.js +23 -0
- package/repos/task-common/frontend/src/components/layout/Topbar.js +13 -0
- package/repos/task-common/frontend/src/config/theme.js +11 -0
- package/repos/task-common/frontend/src/context/ItemContext.js +9 -0
- package/repos/task-common/frontend/src/hooks/useItems.js +30 -0
- package/repos/task-common/frontend/src/hooks/usePagination.js +10 -0
- package/repos/task-common/frontend/src/index.js +11 -0
- package/repos/task-common/frontend/src/pages/DashboardPage.js +30 -0
- package/repos/task-common/frontend/src/pages/ItemsPage.js +36 -0
- package/repos/task-common/frontend/src/pages/ProfilePage.js +9 -0
- package/repos/task-common/frontend/src/utils/date.js +4 -0
- package/repos/task1/README.md +34 -0
- package/repos/task1/backend/.env.example +3 -0
- package/repos/task1/backend/app.js +17 -0
- package/repos/task1/backend/config/db.js +12 -0
- package/repos/task1/backend/controllers/taskController.js +68 -0
- package/repos/task1/backend/data/taskflow-data.json +14 -0
- package/repos/task1/backend/models/Task.js +21 -0
- package/repos/task1/backend/package-lock.json +1462 -0
- package/repos/task1/backend/package.json +25 -0
- package/repos/task1/backend/routes/taskRoutes.js +9 -0
- package/repos/task1/backend/scripts/seed.js +22 -0
- package/repos/task1/backend/server.js +12 -0
- package/repos/task1/frontend/README.md +70 -0
- package/repos/task1/frontend/package-lock.json +17515 -0
- package/repos/task1/frontend/package.json +43 -0
- package/repos/task1/frontend/public/favicon.ico +0 -0
- package/repos/task1/frontend/public/index.html +43 -0
- package/repos/task1/frontend/public/logo192.png +0 -0
- package/repos/task1/frontend/public/logo512.png +0 -0
- package/repos/task1/frontend/public/manifest.json +25 -0
- package/repos/task1/frontend/public/robots.txt +3 -0
- package/repos/task1/frontend/src/App.js +44 -0
- package/repos/task1/frontend/src/App.test.js +10 -0
- package/repos/task1/frontend/src/api/taskService.js +9 -0
- package/repos/task1/frontend/src/components/Dashboard.js +28 -0
- package/repos/task1/frontend/src/components/DashboardTable.js +29 -0
- package/repos/task1/frontend/src/components/Layout.js +15 -0
- package/repos/task1/frontend/src/components/Pagination.js +19 -0
- package/repos/task1/frontend/src/components/PriorityPill.js +4 -0
- package/repos/task1/frontend/src/components/Profile.js +4 -0
- package/repos/task1/frontend/src/components/Sidebar.js +26 -0
- package/repos/task1/frontend/src/components/StatCard.js +6 -0
- package/repos/task1/frontend/src/components/StatusPill.js +4 -0
- package/repos/task1/frontend/src/components/TaskCard.js +22 -0
- package/repos/task1/frontend/src/components/TaskFilters.js +11 -0
- package/repos/task1/frontend/src/components/TaskFormModal.js +35 -0
- package/repos/task1/frontend/src/components/Tasks.js +42 -0
- package/repos/task1/frontend/src/components/Topbar.js +18 -0
- package/repos/task1/frontend/src/components/theme.js +8 -0
- package/repos/task1/frontend/src/index.js +14 -0
- package/repos/task1/screenshots/add-task-form.jpg +0 -0
- package/repos/task1/screenshots/dashboard.jpg +0 -0
- package/repos/task1/screenshots/tasks.jpg +0 -0
package/package.json
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
+
|
|
1
2
|
{
|
|
2
3
|
"name": "react-repos",
|
|
3
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.2",
|
|
4
5
|
"description": "You can’t burn ashes twice, but you can always start a new fire.",
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"author": "madhav",
|
|
7
8
|
"type": "commonjs",
|
|
8
9
|
"main": "index.js",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"react-repos": "^0.0.0-stage",
|
|
14
|
-
"sasa-greet-madhav": "^1.0.0",
|
|
15
|
-
"suhanaa": "^1.0.0"
|
|
16
|
-
}
|
|
10
|
+
"files": [
|
|
11
|
+
"index.js",
|
|
12
|
+
"repos/"
|
|
13
|
+
]
|
|
17
14
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# MERN Common Starter
|
|
2
|
+
|
|
3
|
+
A reusable building-block repository for MERN dashboards and CRUD applications. It uses a Create React App-compatible frontend, Bootstrap-only styling, an Express MVC API, Mongoose validation, MongoDB seed data, and separate components for common interface patterns.
|
|
4
|
+
|
|
5
|
+
## Included building blocks
|
|
6
|
+
|
|
7
|
+
### Backend
|
|
8
|
+
|
|
9
|
+
- Database connection module
|
|
10
|
+
- Generic Mongoose model
|
|
11
|
+
- REST controller and routes for list, detail, create, update, patch, and delete
|
|
12
|
+
- Search and dropdown query filters
|
|
13
|
+
- JSON 404 and error middleware
|
|
14
|
+
- Seed script and sample data
|
|
15
|
+
- Unit-tested query builder
|
|
16
|
+
|
|
17
|
+
### Frontend
|
|
18
|
+
|
|
19
|
+
- Application shell, fixed sidebar, and top bar
|
|
20
|
+
- Page header and action slot
|
|
21
|
+
- Metric cards, badges, progress bars, and entity cards
|
|
22
|
+
- Configurable filter bar and data table
|
|
23
|
+
- Shared pagination hook and component
|
|
24
|
+
- Generic modal and confirmation dialog
|
|
25
|
+
- Reusable loading, error, and empty states
|
|
26
|
+
- Controlled create/edit form
|
|
27
|
+
- Axios service layer, CRUD hook, and React context
|
|
28
|
+
- Example dashboard, CRUD list, and profile routes
|
|
29
|
+
|
|
30
|
+
## Start MongoDB
|
|
31
|
+
|
|
32
|
+
MongoDB must be available at `mongodb://127.0.0.1:27017`. Copy `backend/.env.example` to `backend/.env` if you want to change the database or API port.
|
|
33
|
+
|
|
34
|
+
## Run the backend
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
cd backend
|
|
38
|
+
npm install
|
|
39
|
+
npm run seed
|
|
40
|
+
npm start
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The API runs at `http://localhost:5002`.
|
|
44
|
+
|
|
45
|
+
## Run the frontend
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cd frontend
|
|
49
|
+
npm install
|
|
50
|
+
npm start
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The frontend runs at `http://localhost:3000`. Copy `frontend/.env.example` to `frontend/.env` to override the API URL.
|
|
54
|
+
|
|
55
|
+
## Adapt it to a new project
|
|
56
|
+
|
|
57
|
+
1. Rename `Item` in the backend model, controller, and route modules.
|
|
58
|
+
2. Replace the schema fields and validation rules in `backend/models/Item.js`.
|
|
59
|
+
3. Rename `itemService`, `useItems`, and `ItemContext` in the frontend.
|
|
60
|
+
4. Update `ItemForm`, `ItemCard`, and the page column/filter configuration.
|
|
61
|
+
5. Change branding, colors, navigation, and user text in `frontend/src/config/theme.js` and the layout components.
|
|
62
|
+
|
|
63
|
+
Common components are intentionally domain-neutral, so they can be retained when the entity-specific modules are replaced.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Assembles Express middleware, health check, routes, and error handling.
|
|
2
|
+
const express = require('express');
|
|
3
|
+
const cors = require('cors');
|
|
4
|
+
const itemRoutes = require('./routes/itemRoutes');
|
|
5
|
+
const notFound = require('./middleware/notFound');
|
|
6
|
+
const errorHandler = require('./middleware/errorHandler');
|
|
7
|
+
|
|
8
|
+
const app = express();
|
|
9
|
+
app.use(cors());
|
|
10
|
+
app.use(express.json());
|
|
11
|
+
app.get('/api/health', (req, res) => res.json({ status: 'ok' }));
|
|
12
|
+
app.use('/api/items', itemRoutes);
|
|
13
|
+
app.use(notFound);
|
|
14
|
+
app.use(errorHandler);
|
|
15
|
+
|
|
16
|
+
module.exports = app;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Creates the shared Mongoose connection used by the API and scripts.
|
|
2
|
+
const mongoose = require('mongoose');
|
|
3
|
+
|
|
4
|
+
const connectDatabase = async () => {
|
|
5
|
+
const uri = process.env.MONGODB_URI || 'mongodb://127.0.0.1:27017/mern_common';
|
|
6
|
+
const connection = await mongoose.connect(uri);
|
|
7
|
+
console.log(`MongoDB connected: ${connection.connection.host}`);
|
|
8
|
+
return connection;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
module.exports = connectDatabase;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Implements reusable list, detail, create, update, and delete controller actions.
|
|
2
|
+
const mongoose = require('mongoose');
|
|
3
|
+
const Item = require('../models/Item');
|
|
4
|
+
const { buildQuery } = require('../utils/buildQuery');
|
|
5
|
+
|
|
6
|
+
const findItem = async (id) => {
|
|
7
|
+
if (!mongoose.isValidObjectId(id)) return null;
|
|
8
|
+
return Item.findById(id);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const listItems = async (req, res, next) => {
|
|
12
|
+
try {
|
|
13
|
+
const items = await Item.find(buildQuery(req.query)).sort({ createdAt: -1 });
|
|
14
|
+
res.json(items);
|
|
15
|
+
} catch (error) { next(error); }
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const getItem = async (req, res, next) => {
|
|
19
|
+
try {
|
|
20
|
+
const item = await findItem(req.params.id);
|
|
21
|
+
if (!item) return res.status(404).json({ message: 'Item not found' });
|
|
22
|
+
return res.json(item);
|
|
23
|
+
} catch (error) { return next(error); }
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const createItem = async (req, res, next) => {
|
|
27
|
+
try {
|
|
28
|
+
const item = await Item.create(req.body);
|
|
29
|
+
res.status(201).json(item);
|
|
30
|
+
} catch (error) { next(error); }
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const updateItem = async (req, res, next) => {
|
|
34
|
+
try {
|
|
35
|
+
if (!mongoose.isValidObjectId(req.params.id)) return res.status(400).json({ message: 'Invalid item id' });
|
|
36
|
+
const item = await Item.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true });
|
|
37
|
+
if (!item) return res.status(404).json({ message: 'Item not found' });
|
|
38
|
+
return res.json(item);
|
|
39
|
+
} catch (error) { return next(error); }
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const deleteItem = async (req, res, next) => {
|
|
43
|
+
try {
|
|
44
|
+
if (!mongoose.isValidObjectId(req.params.id)) return res.status(400).json({ message: 'Invalid item id' });
|
|
45
|
+
const item = await Item.findByIdAndDelete(req.params.id);
|
|
46
|
+
if (!item) return res.status(404).json({ message: 'Item not found' });
|
|
47
|
+
return res.json({ message: 'Item deleted' });
|
|
48
|
+
} catch (error) { return next(error); }
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
module.exports = { listItems, getItem, createItem, updateItem, deleteItem };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
[
|
|
2
|
+
{ "name": "Plan the interface", "description": "Create the initial screen structure", "priority": "High", "status": "In Progress", "dueDate": "2026-11-01", "progress": 60 },
|
|
3
|
+
{ "name": "Connect the API", "description": "Wire the client to the REST service", "priority": "Medium", "status": "To Do", "dueDate": "2026-11-05", "progress": 20 },
|
|
4
|
+
{ "name": "Review the release", "description": "Perform the final quality review", "priority": "Low", "status": "Review", "dueDate": "2026-11-08", "progress": 85 }
|
|
5
|
+
]
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Converts application and Mongoose errors into consistent JSON responses.
|
|
2
|
+
const errorHandler = (error, req, res, next) => {
|
|
3
|
+
if (res.headersSent) return next(error);
|
|
4
|
+
const status = error.name === 'ValidationError' ? 400 : error.status || 500;
|
|
5
|
+
return res.status(status).json({ message: error.message || 'Internal server error' });
|
|
6
|
+
};
|
|
7
|
+
module.exports = errorHandler;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Defines a reusable work-item model that can be renamed for a domain entity.
|
|
2
|
+
const mongoose = require('mongoose');
|
|
3
|
+
|
|
4
|
+
const itemSchema = new mongoose.Schema(
|
|
5
|
+
{
|
|
6
|
+
name: { type: String, required: true, trim: true },
|
|
7
|
+
description: { type: String, default: '', trim: true },
|
|
8
|
+
priority: { type: String, enum: ['High', 'Medium', 'Low'], default: 'Medium' },
|
|
9
|
+
status: { type: String, enum: ['To Do', 'In Progress', 'Review', 'Done'], default: 'To Do' },
|
|
10
|
+
dueDate: { type: Date, required: true },
|
|
11
|
+
progress: { type: Number, min: 0, max: 100, default: 0 },
|
|
12
|
+
},
|
|
13
|
+
{ timestamps: true }
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
module.exports = mongoose.model('Item', itemSchema);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mern-common-backend",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "Reusable Express and MongoDB CRUD API boilerplate",
|
|
6
|
+
"main": "server.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "node server.js",
|
|
9
|
+
"dev": "nodemon server.js",
|
|
10
|
+
"seed": "node scripts/seed.js",
|
|
11
|
+
"test": "node --test"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"cors": "^2.8.6",
|
|
15
|
+
"dotenv": "^18.0.0",
|
|
16
|
+
"express": "^5.1.0",
|
|
17
|
+
"mongoose": "^9.0.0"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"nodemon": "^3.1.10"
|
|
21
|
+
}
|
|
22
|
+
}
|