diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..b48da26 --- /dev/null +++ b/.env.example @@ -0,0 +1,10 @@ +# Environment variables +PORT=5000 +MONGODB_URI=mongodb://localhost:27017/oneroom + +# REQUIRED: Set a strong secret key for JWT tokens +# Generate a random string using: openssl rand -base64 32 +JWT_SECRET= + +# Client URL (for CORS) +CLIENT_URL=http://localhost:3000 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a6e3c53 --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +# Dependencies +node_modules/ +package-lock.json + +# Environment +.env + +# Logs +logs +*.log +npm-debug.log* + +# Build +dist/ +build/ +client/build/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo + +# OS +.DS_Store +Thumbs.db + +# Testing +coverage/ + +# Temporary +tmp/ +temp/ diff --git a/FEATURES.md b/FEATURES.md new file mode 100644 index 0000000..623d77f --- /dev/null +++ b/FEATURES.md @@ -0,0 +1,296 @@ +# OneRoom - Feature Documentation + +## Overview +OneRoom is a comprehensive roommate management application that simplifies shared living by automating expense splitting and task assignment. + +## Core Features + +### 1. User Authentication & Authorization +- **Secure Registration & Login**: JWT-based authentication with bcrypt password hashing (12 salt rounds) +- **Protected Routes**: All API endpoints require authentication +- **Rate Limiting**: + - Authentication endpoints: 5 requests per 15 minutes + - Create operations: 30 requests per 15 minutes + - General API: 100 requests per 15 minutes + +### 2. Room Management +- **Create Rooms**: Users can create multiple living spaces +- **Unique Invite Codes**: Each room gets a unique 8-character code for easy sharing +- **Role-Based Access**: + - Admin: Can modify room settings and remove members + - Member: Can participate and view room content +- **Multi-Room Support**: Users can join and manage multiple rooms simultaneously + +### 3. Expense Management + +#### Expense Tracking +- Add expenses with description, amount, and category +- Categories: Groceries, Utilities, Rent, Entertainment, Other +- Automatic timestamp for all expenses +- View expense history by room + +#### Smart Splitting +- **Equal Split (Default)**: Automatically divides expenses equally among all roommates +- **Custom Percentage Split**: Set custom percentages for different split scenarios +- Precise calculation with 2 decimal places + +#### Balance Calculation +- Real-time calculation of who owes whom +- Smart settlement algorithm minimizes the number of transactions needed +- Clear settlement recommendations (e.g., "Alice owes Bob $25.50") +- Mark individual splits as settled when paid + +#### Settlement Features +- Track settlement status per person per expense +- Calculate net balances across all expenses +- Optimized settlement plan to minimize transactions + +### 4. Task Management + +#### Task Creation & Organization +- Create tasks with title, description, and category +- Categories: Cleaning, Cooking, Shopping, Maintenance, Other +- Set priority levels: Low, Medium, High +- Add due dates for time-sensitive tasks +- Track status: Pending, In Progress, Completed + +#### Automatic Task Assignment +- **Fair Distribution Algorithm**: + - Tracks assignment history per category + - Assigns tasks to the member with least recent assignments + - Tie-breaker: Assigns to member who was assigned longest ago + - Ensures fair rotation across all roommates + +#### Recurring Tasks +- Set tasks to recur: Daily, Weekly, or Monthly +- **Auto-Rotation**: When completed, automatically creates next occurrence and assigns to next person +- Smart date calculation: + - Daily: Adds 1 day + - Weekly: Adds 7 days + - Monthly: Handles month-end edge cases (e.g., Jan 31 → Feb 28) + +#### Personal Task Dashboard +- View all assigned tasks across all rooms +- Filter by status (All, Pending, In Progress, Completed) +- Quick actions: Start task, Mark as complete +- See task details including room, priority, and due date + +### 5. User Interface + +#### Responsive Design +- Mobile-first responsive layout +- Works seamlessly on desktop, tablet, and mobile +- Modern gradient-based color scheme (purple to blue) +- Smooth animations and transitions + +#### Dashboard +- Overview of all rooms and pending tasks +- Quick stats: Number of rooms, pending tasks +- Recent tasks preview +- Easy access to create or join rooms + +#### Room Details View +- Tabbed interface: Overview, Expenses, Tasks, Members +- **Overview Tab**: Key statistics and settlement summary +- **Expenses Tab**: Complete expense list with add functionality +- **Tasks Tab**: All room tasks with filtering and quick actions +- **Members Tab**: Room member list with roles + +#### Navigation +- Clean navbar with user profile display +- Quick access to Dashboard and My Tasks +- One-click logout + +### 6. Security Features + +#### Authentication Security +- Passwords hashed with bcrypt (12 salt rounds) +- JWT tokens with 7-day expiration +- Secure token storage in localStorage +- Automatic redirect on token expiration + +#### Rate Limiting +- Prevents brute force attacks on login +- Protects against spam and abuse +- Different limits for different operation types +- Standard rate limit headers in responses + +#### API Security +- All routes require authentication (except login/register) +- Input validation on all endpoints +- CORS enabled for cross-origin requests +- Error messages don't leak sensitive information + +#### Environment Security +- JWT_SECRET validation (fails in production if not set) +- Development fallback with clear warnings +- Secure defaults for all configurations + +### 7. Data Models + +#### User Model +- Name, email (unique), password (hashed) +- Associated rooms (array of references) +- Creation timestamp + +#### Room Model +- Name, description +- Members with roles and join dates +- Unique invite code +- Creator reference and creation date + +#### Expense Model +- Description, amount, category +- Paid by reference +- Split between (array with user references, amounts, settled status) +- Date and creation timestamp + +#### Task Model +- Title, description, category +- Assigned to reference +- Status, priority +- Recurring configuration (enabled, frequency, auto-assign) +- Due date, completion date +- Creation timestamp + +## Technical Architecture + +### Backend Stack +- **Runtime**: Node.js +- **Framework**: Express.js +- **Database**: MongoDB with Mongoose ODM +- **Authentication**: JWT + bcryptjs +- **Security**: express-rate-limit, CORS +- **Utilities**: uuid (for invite codes) + +### Frontend Stack +- **Library**: React 18 +- **Routing**: React Router DOM v6 +- **HTTP Client**: Axios +- **Styling**: Custom CSS3 with modern features +- **Build Tool**: Create React App + +### API Structure +- RESTful API design +- JSON request/response format +- Consistent error handling +- Standard HTTP status codes +- Bearer token authentication + +## Algorithms + +### Expense Settlement Algorithm +1. Initialize balance for each member to 0 +2. For each expense: + - Credit the payer with the full amount + - Debit each person in the split for their share +3. Separate members into debtors (negative balance) and creditors (positive balance) +4. Create minimum transactions: + - Match smallest debt with smallest credit + - Create settlement transaction + - Continue until all balances are zero + +### Task Assignment Algorithm +1. Get recent task history for the category +2. Count assignments per member +3. Track last assignment date per member +4. Find members with minimum assignment count +5. If tie, select member assigned longest ago (or never assigned) +6. Return selected member for assignment + +### Recurring Task Rotation +1. When task is marked complete: + - Create new task instance with same properties + - Calculate next due date based on frequency + - Use assignment algorithm to get next assignee + - Save new task and mark original as complete + +## Future Enhancement Possibilities + +### Potential Features +- Push notifications for new expenses and tasks +- Mobile app (React Native) +- Expense categories analytics and charts +- Task completion statistics +- Shopping lists with auto-assignment +- Calendar integration for tasks +- Bill reminders and recurring expenses +- Photo attachments for expenses +- Task comments and discussions +- Room announcements board +- Integration with payment apps (Venmo, PayPal) +- Export data (CSV, PDF reports) +- Dark mode theme +- Multiple language support + +### Scalability Considerations +- Database indexing for performance +- Caching layer (Redis) +- Background job processing for recurring tasks +- WebSocket for real-time updates +- CDN for static assets +- Load balancing for high traffic +- Database replication and backups + +## Development Guidelines + +### Running Locally +1. Install MongoDB and ensure it's running +2. Copy `.env.example` to `.env` and configure +3. Run `npm install` and `cd client && npm install` +4. Start with `npm run dev-all` for full stack development + +### Code Quality +- All routes include rate limiting +- Authentication required for protected endpoints +- Input validation on all user data +- Consistent error handling patterns +- Comments for complex algorithms +- Modular code organization + +### Security Checklist +- ✅ Password hashing (bcrypt with 12 rounds) +- ✅ JWT token authentication +- ✅ Rate limiting on all endpoints +- ✅ Environment variable validation +- ✅ Protected routes +- ✅ CORS configuration +- ✅ No sensitive data in error messages +- ✅ Input validation +- ✅ No hardcoded secrets in production + +## API Endpoints Summary + +### Authentication +- POST `/api/users/register` - Create new account +- POST `/api/users/login` - Authenticate user +- GET `/api/users/me` - Get current user +- PUT `/api/users/me` - Update profile + +### Rooms +- POST `/api/rooms` - Create room +- GET `/api/rooms` - List user's rooms +- GET `/api/rooms/:id` - Get room details +- POST `/api/rooms/join` - Join with invite code +- PUT `/api/rooms/:id` - Update room +- DELETE `/api/rooms/:id/members/:userId` - Remove member + +### Expenses +- POST `/api/expenses` - Add expense +- GET `/api/expenses/room/:roomId` - List room expenses +- GET `/api/expenses/room/:roomId/balances` - Get balances +- PUT `/api/expenses/:id` - Update expense +- PUT `/api/expenses/:id/settle/:userId` - Mark settled +- DELETE `/api/expenses/:id` - Delete expense + +### Tasks +- POST `/api/tasks` - Create task +- GET `/api/tasks/room/:roomId` - List room tasks +- GET `/api/tasks/my-tasks` - Get user's tasks +- PUT `/api/tasks/:id/status` - Update status +- PUT `/api/tasks/:id` - Update task +- DELETE `/api/tasks/:id` - Delete task +- POST `/api/tasks/room/:roomId/rotate` - Manual rotation + +## License +MIT License - Free to use and modify diff --git a/FUTURE_IMPROVEMENTS.md b/FUTURE_IMPROVEMENTS.md new file mode 100644 index 0000000..5d6dbb4 --- /dev/null +++ b/FUTURE_IMPROVEMENTS.md @@ -0,0 +1,177 @@ +# Future Improvements & Enhancement Ideas + +This document tracks potential improvements and enhancements for OneRoom. + +## Code Quality Improvements + +### High Priority +- [ ] Replace browser `alert()` calls with toast notifications or inline error messages + - Affects: Dashboard.js, MyTasks.js, RoomDetails.js + - Benefit: Better user experience with non-blocking notifications + +### Medium Priority +- [ ] Fix task priority sorting to use numeric values + - Current: Alphabetic sort on string values + - Better: Map priority to numbers (high=3, medium=2, low=1) for correct sorting + +- [ ] Use safer hasOwnProperty checks + - Change: `assignmentCounts.hasOwnProperty(userId)` + - To: `Object.prototype.hasOwnProperty.call(assignmentCounts, userId)` or `userId in assignmentCounts` + +### Low Priority +- [ ] Preserve custom split proportions when updating expense amounts + - Current behavior: Reverts to equal split when amount is changed + - Better: Maintain percentage proportions or ask user for confirmation + +## Feature Enhancements + +### User Experience +- [ ] Add toast/snackbar notification system +- [ ] Add loading spinners for async operations +- [ ] Add confirmation dialogs for destructive actions (delete expense, remove member) +- [ ] Add success messages after successful operations +- [ ] Add keyboard shortcuts for common actions +- [ ] Add drag-and-drop for task reordering +- [ ] Add dark mode theme toggle + +### Functionality +- [ ] Add expense categories statistics/charts +- [ ] Add task completion history and statistics +- [ ] Add recurring expenses feature +- [ ] Add expense receipt photo uploads +- [ ] Add task comments and discussion threads +- [ ] Add room announcement board +- [ ] Add shopping list feature with auto-assignment +- [ ] Add bill reminders +- [ ] Add calendar view for tasks with due dates + +### Mobile Experience +- [ ] Add pull-to-refresh on mobile +- [ ] Add swipe gestures for common actions +- [ ] Optimize touch targets for mobile +- [ ] Add PWA support for offline functionality +- [ ] Create native mobile app (React Native) + +### Notifications +- [ ] Add email notifications for new expenses +- [ ] Add push notifications for task assignments +- [ ] Add daily task reminder emails +- [ ] Add expense settlement reminders +- [ ] Add in-app notification center + +### Integration +- [ ] Integrate with payment apps (Venmo, PayPal, Zelle) +- [ ] Add calendar integration (Google Calendar, iCal) +- [ ] Add OAuth social login (Google, Facebook) +- [ ] Add expense export to CSV/Excel +- [ ] Add PDF report generation +- [ ] Add API for third-party integrations + +### Analytics & Insights +- [ ] Add spending analytics by category +- [ ] Add monthly expense trends +- [ ] Add task completion rate per member +- [ ] Add expense vs budget tracking +- [ ] Add member contribution fairness metrics + +### Administration +- [ ] Add room archives for old/inactive rooms +- [ ] Add data export for entire room +- [ ] Add room templates for common setups +- [ ] Add bulk task creation +- [ ] Add expense templates for recurring expenses + +## Performance Optimizations + +- [ ] Add database indexing for frequently queried fields +- [ ] Implement caching layer (Redis) for balance calculations +- [ ] Add pagination for large expense/task lists +- [ ] Optimize bundle size with code splitting +- [ ] Add service worker for offline support +- [ ] Implement lazy loading for components +- [ ] Add request debouncing for search/filter operations + +## DevOps & Infrastructure + +- [ ] Set up CI/CD pipeline +- [ ] Add automated testing (unit, integration, e2e) +- [ ] Set up monitoring and error tracking (Sentry) +- [ ] Add performance monitoring (New Relic, DataDog) +- [ ] Set up database backups +- [ ] Add health check endpoints +- [ ] Create Docker containers for easy deployment +- [ ] Add staging environment +- [ ] Set up log aggregation (ELK stack) + +## Documentation + +- [ ] Add API documentation with Swagger/OpenAPI +- [ ] Create video tutorials for common workflows +- [ ] Add inline help tooltips in UI +- [ ] Create developer contribution guide +- [ ] Add architecture diagrams +- [ ] Create troubleshooting guide +- [ ] Add FAQ section + +## Testing + +- [ ] Add unit tests for utilities and algorithms +- [ ] Add integration tests for API endpoints +- [ ] Add E2E tests for critical user flows +- [ ] Add performance testing +- [ ] Add security testing (OWASP) +- [ ] Add accessibility testing (WCAG compliance) + +## Security Enhancements + +- [ ] Add two-factor authentication (2FA) +- [ ] Add password strength requirements and validation +- [ ] Add session management and device tracking +- [ ] Add audit logs for sensitive operations +- [ ] Add CAPTCHA for registration/login +- [ ] Add content security policy (CSP) headers +- [ ] Add rate limiting per user (not just per IP) +- [ ] Add account recovery mechanism +- [ ] Add data encryption at rest + +## Accessibility + +- [ ] Add ARIA labels for screen readers +- [ ] Ensure keyboard navigation works throughout app +- [ ] Add high contrast mode +- [ ] Ensure proper heading hierarchy +- [ ] Add alt text for all images +- [ ] Test with screen readers +- [ ] Add focus indicators +- [ ] Ensure minimum contrast ratios + +## Internationalization + +- [ ] Add multi-language support (i18n) +- [ ] Support different currency formats +- [ ] Support different date/time formats +- [ ] Add RTL language support +- [ ] Translate all user-facing text +- [ ] Support locale-specific number formatting + +## Community & Social + +- [ ] Add user feedback/suggestion system +- [ ] Create public roadmap +- [ ] Add social sharing features +- [ ] Create community forum or Discord +- [ ] Add referral program +- [ ] Create blog for updates and tips + +--- + +## Notes + +This list is continuously evolving. Priority and feasibility of each item should be evaluated based on: +- User feedback and requests +- Development resources available +- Impact on user experience +- Technical complexity +- Maintenance burden + +Not all items need to be implemented - focus should be on features that provide the most value to users while maintaining code quality and security. diff --git a/README.md b/README.md index cc5b80d..ea28709 100644 --- a/README.md +++ b/README.md @@ -1 +1,253 @@ -# oneroom \ No newline at end of file +# 🏠 OneRoom - Roommate Management Application + +OneRoom is a comprehensive web application designed to simplify roommate life by managing shared expenses and automatically assigning daily tasks among roommates. + +## ✨ Features + +### 💰 Expense Management +- **Easy Expense Tracking**: Add and track all shared expenses +- **Automatic Splitting**: Expenses are automatically split equally among all roommates +- **Custom Splits**: Support for custom percentage-based splits +- **Category Organization**: Categorize expenses (groceries, utilities, rent, entertainment, etc.) +- **Balance Calculation**: Automatic calculation of who owes whom +- **Settlement Tracking**: Mark expenses as settled when payments are made +- **Smart Settlement Plan**: Minimizes the number of transactions needed to settle all debts + +### ✅ Task Management +- **Task Assignment**: Create and assign tasks to roommates +- **Auto-Assignment**: Fair rotation system that automatically assigns tasks +- **Recurring Tasks**: Set up daily, weekly, or monthly recurring tasks with auto-rotation +- **Task Categories**: Organize tasks by type (cleaning, cooking, shopping, maintenance) +- **Priority Levels**: Set task priorities (low, medium, high) +- **Status Tracking**: Track task status (pending, in-progress, completed) +- **Due Dates**: Set and track task deadlines +- **Personal Dashboard**: View all your assigned tasks in one place + +### 👥 Room & User Management +- **Multiple Rooms**: Support for multiple shared living spaces +- **Easy Onboarding**: Simple registration and login +- **Invite System**: Unique invite codes for each room +- **Role-Based Access**: Admin and member roles with appropriate permissions +- **Member Management**: Add/remove members from rooms + +### 🎨 Additional Features +- **Responsive Design**: Works seamlessly on desktop and mobile devices +- **Intuitive Dashboard**: Clean overview of all your rooms, expenses, and tasks +- **Real-time Updates**: Instant updates when roommates add expenses or tasks +- **Attractive UI**: Modern, gradient-based design with smooth animations +- **Secure Authentication**: JWT-based authentication with password hashing + +## 🚀 Getting Started + +### Prerequisites +- Node.js (v14 or higher) +- MongoDB (local or cloud instance) +- npm or yarn + +### Installation + +1. **Clone the repository** +```bash +git clone https://github.com/mohdrazakhan/oneroom.git +cd oneroom +``` + +2. **Install dependencies** +```bash +# Install server dependencies +npm install + +# Install client dependencies +cd client +npm install +cd .. +``` + +3. **Set up environment variables** +```bash +# Copy the example env file +cp .env.example .env + +# Edit .env with your configuration +# Required variables: +# - MONGODB_URI: Your MongoDB connection string +# - JWT_SECRET: A secure random string for JWT tokens +# - PORT: Server port (default: 5000) +``` + +4. **Start MongoDB** +```bash +# If running MongoDB locally +mongod +``` + +5. **Run the application** + +Development mode (runs both server and client): +```bash +npm run dev-all +``` + +Or run separately: +```bash +# Terminal 1 - Start the server +npm run dev + +# Terminal 2 - Start the client +npm run client +``` + +The application will be available at: +- Frontend: http://localhost:3000 +- Backend API: http://localhost:5000 + +### Production Build + +```bash +# Build the client +npm run build + +# Start the server +npm start +``` + +## 📖 Usage Guide + +### Creating Your First Room + +1. **Register/Login**: Create an account or login +2. **Create a Room**: Click "Create Room" on the dashboard +3. **Share Invite Code**: Share the generated invite code with your roommates +4. **They Join**: Roommates use the invite code to join your room + +### Managing Expenses + +1. **Add an Expense**: + - Go to your room + - Click "Add Expense" in the Expenses tab + - Enter description, amount, and category + - The expense will be automatically split equally among all members + +2. **View Balances**: + - Check the Overview tab to see who owes whom + - The app calculates the minimum number of transactions needed + +3. **Settle Up**: + - When someone pays their share, mark it as settled + - The balance summary updates automatically + +### Managing Tasks + +1. **Create a Task**: + - Go to your room + - Click "Add Task" in the Tasks tab + - Set title, category, priority, and due date + - The task will be auto-assigned fairly + +2. **Recurring Tasks**: + - Enable "Recurring Task" when creating + - Choose frequency (daily, weekly, monthly) + - Tasks automatically rotate to the next person after completion + +3. **Complete Tasks**: + - View your tasks in "My Tasks" + - Click "Complete" when done + - For recurring tasks, a new instance is created and assigned to the next person + +## 🏗️ Project Structure + +``` +oneroom/ +├── client/ # React frontend +│ ├── public/ +│ └── src/ +│ ├── components/ # Reusable components +│ ├── pages/ # Page components +│ ├── services/ # API services +│ └── utils/ # Utility functions +├── server/ # Express backend +│ ├── controllers/ # Route controllers +│ ├── middleware/ # Custom middleware +│ ├── models/ # MongoDB models +│ ├── routes/ # API routes +│ ├── utils/ # Utility functions +│ └── index.js # Server entry point +├── .env.example # Example environment variables +├── .gitignore +├── package.json +└── README.md +``` + +## 🛠️ Tech Stack + +### Frontend +- **React 18**: UI library +- **React Router**: Client-side routing +- **Axios**: HTTP client +- **CSS3**: Styling with modern features + +### Backend +- **Node.js**: Runtime environment +- **Express**: Web framework +- **MongoDB**: Database +- **Mongoose**: ODM for MongoDB +- **JWT**: Authentication +- **bcryptjs**: Password hashing + +## 🔐 Security + +- Passwords are hashed using bcrypt +- JWT tokens for secure authentication +- Protected API routes with authentication middleware +- Input validation and sanitization +- CORS enabled for cross-origin requests + +## 📱 API Documentation + +### Authentication +- `POST /api/users/register` - Register new user +- `POST /api/users/login` - Login user +- `GET /api/users/me` - Get current user profile +- `PUT /api/users/me` - Update user profile + +### Rooms +- `POST /api/rooms` - Create new room +- `GET /api/rooms` - Get all user's rooms +- `GET /api/rooms/:id` - Get room details +- `POST /api/rooms/join` - Join room with invite code +- `PUT /api/rooms/:id` - Update room +- `DELETE /api/rooms/:id/members/:userId` - Remove member + +### Expenses +- `POST /api/expenses` - Create expense +- `GET /api/expenses/room/:roomId` - Get room expenses +- `GET /api/expenses/room/:roomId/balances` - Get balance summary +- `PUT /api/expenses/:id` - Update expense +- `PUT /api/expenses/:id/settle/:userId` - Mark as settled +- `DELETE /api/expenses/:id` - Delete expense + +### Tasks +- `POST /api/tasks` - Create task +- `GET /api/tasks/room/:roomId` - Get room tasks +- `GET /api/tasks/my-tasks` - Get user's tasks +- `PUT /api/tasks/:id/status` - Update task status +- `PUT /api/tasks/:id` - Update task +- `DELETE /api/tasks/:id` - Delete task +- `POST /api/tasks/room/:roomId/rotate` - Rotate recurring tasks + +## 🤝 Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. + +## 📝 License + +This project is licensed under the MIT License. + +## 👨‍💻 Author + +Created with ❤️ for making roommate life easier! + +## 🙏 Acknowledgments + +- Thanks to all roommates who inspired this project +- Built with modern web technologies for the best user experience \ No newline at end of file diff --git a/client/package.json b/client/package.json new file mode 100644 index 0000000..7f0f60b --- /dev/null +++ b/client/package.json @@ -0,0 +1,36 @@ +{ + "name": "oneroom-client", + "version": "1.0.0", + "private": true, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.11.0", + "axios": "^1.4.0", + "react-scripts": "5.0.1" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "react-app" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "proxy": "http://localhost:5000" +} diff --git a/client/public/index.html b/client/public/index.html new file mode 100644 index 0000000..e51bdd4 --- /dev/null +++ b/client/public/index.html @@ -0,0 +1,14 @@ + + + + + + + + OneRoom - Roommate Management + + + +
+ + diff --git a/client/src/App.js b/client/src/App.js new file mode 100644 index 0000000..f9fc31c --- /dev/null +++ b/client/src/App.js @@ -0,0 +1,74 @@ +import React, { useState, useEffect } from 'react'; +import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; +import Navbar from './components/Navbar'; +import Login from './pages/Login'; +import Register from './pages/Register'; +import Dashboard from './pages/Dashboard'; +import RoomDetails from './pages/RoomDetails'; +import MyTasks from './pages/MyTasks'; + +function App() { + const [user, setUser] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + // Check if user is logged in + const token = localStorage.getItem('token'); + const savedUser = localStorage.getItem('user'); + + if (token && savedUser) { + setUser(JSON.parse(savedUser)); + } + setLoading(false); + }, []); + + const handleLogin = (userData, token) => { + localStorage.setItem('token', token); + localStorage.setItem('user', JSON.stringify(userData)); + setUser(userData); + }; + + const handleLogout = () => { + localStorage.removeItem('token'); + localStorage.removeItem('user'); + setUser(null); + }; + + if (loading) { + return
Loading...
; + } + + return ( + +
+ {user && } +
+ + : } + /> + : } + /> + : } + /> + : } + /> + : } + /> + +
+
+
+ ); +} + +export default App; diff --git a/client/src/components/Navbar.js b/client/src/components/Navbar.js new file mode 100644 index 0000000..ea6bcf6 --- /dev/null +++ b/client/src/components/Navbar.js @@ -0,0 +1,20 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; + +function Navbar({ user, onLogout }) { + return ( + + ); +} + +export default Navbar; diff --git a/client/src/index.css b/client/src/index.css new file mode 100644 index 0000000..adbcbfc --- /dev/null +++ b/client/src/index.css @@ -0,0 +1,382 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; +} + +.app-container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; +} + +/* Navigation */ +.navbar { + background: rgba(255, 255, 255, 0.95); + padding: 1rem 2rem; + border-radius: 10px; + margin-bottom: 2rem; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + display: flex; + justify-content: space-between; + align-items: center; +} + +.navbar h1 { + color: #667eea; + font-size: 1.5rem; +} + +.nav-links { + display: flex; + gap: 1rem; + align-items: center; +} + +.nav-links a { + text-decoration: none; + color: #333; + padding: 0.5rem 1rem; + border-radius: 5px; + transition: background 0.3s; +} + +.nav-links a:hover, +.nav-links a.active { + background: #667eea; + color: white; +} + +/* Buttons */ +.btn { + padding: 0.75rem 1.5rem; + border: none; + border-radius: 5px; + cursor: pointer; + font-size: 1rem; + transition: all 0.3s; + font-weight: 500; +} + +.btn-primary { + background: #667eea; + color: white; +} + +.btn-primary:hover { + background: #5568d3; + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); +} + +.btn-secondary { + background: #6c757d; + color: white; +} + +.btn-secondary:hover { + background: #5a6268; +} + +.btn-success { + background: #28a745; + color: white; +} + +.btn-danger { + background: #dc3545; + color: white; +} + +.btn-small { + padding: 0.5rem 1rem; + font-size: 0.9rem; +} + +/* Cards */ +.card { + background: white; + padding: 2rem; + border-radius: 10px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + margin-bottom: 1.5rem; +} + +.card h2 { + color: #333; + margin-bottom: 1rem; +} + +.card h3 { + color: #555; + margin-bottom: 0.5rem; +} + +/* Forms */ +.form-group { + margin-bottom: 1.5rem; +} + +.form-group label { + display: block; + margin-bottom: 0.5rem; + color: #333; + font-weight: 500; +} + +.form-group input, +.form-group select, +.form-group textarea { + width: 100%; + padding: 0.75rem; + border: 1px solid #ddd; + border-radius: 5px; + font-size: 1rem; + transition: border-color 0.3s; +} + +.form-group input:focus, +.form-group select:focus, +.form-group textarea:focus { + outline: none; + border-color: #667eea; +} + +.form-group textarea { + resize: vertical; + min-height: 100px; +} + +/* Auth Pages */ +.auth-container { + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + padding: 20px; +} + +.auth-card { + background: white; + padding: 3rem; + border-radius: 10px; + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); + max-width: 400px; + width: 100%; +} + +.auth-card h2 { + text-align: center; + color: #667eea; + margin-bottom: 2rem; +} + +/* Dashboard */ +.dashboard-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 1.5rem; + margin-bottom: 2rem; +} + +.stat-card { + background: white; + padding: 1.5rem; + border-radius: 10px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + text-align: center; +} + +.stat-card h3 { + color: #667eea; + font-size: 2rem; + margin-bottom: 0.5rem; +} + +.stat-card p { + color: #666; +} + +/* Lists */ +.list-item { + background: #f8f9fa; + padding: 1rem; + margin-bottom: 1rem; + border-radius: 5px; + border-left: 4px solid #667eea; + display: flex; + justify-content: space-between; + align-items: center; +} + +.list-item:hover { + background: #e9ecef; +} + +.list-item-content h4 { + color: #333; + margin-bottom: 0.25rem; +} + +.list-item-content p { + color: #666; + font-size: 0.9rem; +} + +.list-item-actions { + display: flex; + gap: 0.5rem; +} + +/* Tags */ +.tag { + display: inline-block; + padding: 0.25rem 0.75rem; + border-radius: 20px; + font-size: 0.85rem; + font-weight: 500; + margin-right: 0.5rem; +} + +.tag-pending { + background: #ffc107; + color: #000; +} + +.tag-completed { + background: #28a745; + color: white; +} + +.tag-in-progress { + background: #007bff; + color: white; +} + +.tag-high { + background: #dc3545; + color: white; +} + +.tag-medium { + background: #ffc107; + color: #000; +} + +.tag-low { + background: #6c757d; + color: white; +} + +/* Modal */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.modal-content { + background: white; + padding: 2rem; + border-radius: 10px; + max-width: 500px; + width: 90%; + max-height: 90vh; + overflow-y: auto; +} + +.modal-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1.5rem; +} + +.modal-header h3 { + color: #333; +} + +.close-btn { + background: none; + border: none; + font-size: 1.5rem; + cursor: pointer; + color: #666; +} + +/* Error/Success Messages */ +.alert { + padding: 1rem; + border-radius: 5px; + margin-bottom: 1rem; +} + +.alert-error { + background: #f8d7da; + color: #721c24; + border: 1px solid #f5c6cb; +} + +.alert-success { + background: #d4edda; + color: #155724; + border: 1px solid #c3e6cb; +} + +/* Loading */ +.loading { + text-align: center; + padding: 2rem; + color: white; + font-size: 1.2rem; +} + +/* Responsive */ +@media (max-width: 768px) { + .navbar { + flex-direction: column; + gap: 1rem; + } + + .nav-links { + flex-direction: column; + width: 100%; + } + + .nav-links a { + width: 100%; + text-align: center; + } + + .dashboard-grid { + grid-template-columns: 1fr; + } + + .list-item { + flex-direction: column; + align-items: flex-start; + gap: 1rem; + } + + .list-item-actions { + width: 100%; + justify-content: flex-end; + } +} diff --git a/client/src/index.js b/client/src/index.js new file mode 100644 index 0000000..2cb1087 --- /dev/null +++ b/client/src/index.js @@ -0,0 +1,11 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import './index.css'; +import App from './App'; + +const root = ReactDOM.createRoot(document.getElementById('root')); +root.render( + + + +); diff --git a/client/src/pages/Dashboard.js b/client/src/pages/Dashboard.js new file mode 100644 index 0000000..e145ba1 --- /dev/null +++ b/client/src/pages/Dashboard.js @@ -0,0 +1,216 @@ +import React, { useState, useEffect } from 'react'; +import { Link } from 'react-router-dom'; +import { roomAPI, taskAPI } from '../services/api'; + +function Dashboard({ user }) { + const [rooms, setRooms] = useState([]); + const [myTasks, setMyTasks] = useState([]); + const [showCreateRoom, setShowCreateRoom] = useState(false); + const [showJoinRoom, setShowJoinRoom] = useState(false); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(''); + + useEffect(() => { + fetchData(); + }, []); + + const fetchData = async () => { + try { + const [roomsRes, tasksRes] = await Promise.all([ + roomAPI.getAll(), + taskAPI.getMyTasks('pending') + ]); + setRooms(roomsRes.data); + setMyTasks(tasksRes.data.slice(0, 5)); // Show only 5 recent tasks + setLoading(false); + } catch (err) { + setError('Failed to load data'); + setLoading(false); + } + }; + + const CreateRoomModal = () => { + const [formData, setFormData] = useState({ name: '', description: '' }); + const [creating, setCreating] = useState(false); + + const handleSubmit = async (e) => { + e.preventDefault(); + setCreating(true); + try { + await roomAPI.create(formData); + setShowCreateRoom(false); + fetchData(); + } catch (err) { + alert(err.response?.data?.error || 'Failed to create room'); + } finally { + setCreating(false); + } + }; + + return ( +
setShowCreateRoom(false)}> +
e.stopPropagation()}> +
+

Create New Room

+ +
+
+
+ + setFormData({ ...formData, name: e.target.value })} + required + /> +
+
+ +