TeamUP is a project and activity management platform built to explore and master the Laravel ecosystem, from RESTful API design with Sanctum authentication to Eloquent ORM relationships and scheduled commands.
The backend is a fully structured Laravel 12 REST API, while the frontend is a React + TypeScript SPA built with Vite, consuming the API via Axios with token-based auth.
- Laravel 12 (PHP 8.2+)
- Laravel Sanctum — token-based API authentication
- Eloquent ORM — models, relationships, eager loading
- Laravel Scheduler — automated activity expiration via scheduled command
- RESTful API — resource controllers, middleware, route groups
- React 19 + TypeScript
- Vite
- Zustand (auth state management)
- Axios (API client with auth interceptor)
- React Router DOM v7
- Tailwind CSS v4
The API follows Laravel conventions with route-based resource separation, middleware protection, and clean controller logic.
routes/api.php → API route definitions
app/Http/Controllers/ → AuthController, UserController, ProjectController, ActivityController
app/Http/Middleware/ → RoleMiddleware (admin/user access control)
app/Models/ → User, Project, Activity (with Eloquent relations)
app/Console/Commands/ → ExpireActivities (scheduled command)
Key Laravel features used:
- Sanctum for stateless API token authentication
- RoleMiddleware restricting admin-only routes
- Eloquent eager loading for relations (project users, activities, owner)
- Scheduled command to automatically mark overdue activities as
expired - Unique token generation on project creation (join via token)
- Form Request validation across all endpoints
src/
├── api/ → axios instance with auth interceptor
├── services/ → authService, userService, projectService, activityService
├── store/ → Zustand auth store (persisted)
├── types/ → TypeScript types for all entities
├── components/ → Header, modals, cards, StatsCards, ConfirmationModal...
├── pages/ → Home, ProjectsList, ActivitiesList, ProjectPage, ActivityPage, ProfilePage...
└── routes/ → PrivateRoute, PublicRoute, RedirectByRole...
Authentication is handled by Laravel Sanctum, issuing API tokens on login. Every protected request includes an Authorization: Bearer TOKEN header injected automatically by the Axios interceptor.
Role-based access control is enforced on the backend via RoleMiddleware:
| Role | Access |
|---|---|
admin |
Create/delete projects, manage users, view all data |
user |
Join projects, manage assigned activities, view own data |
users → id, name, email, password, role (admin/user)
projects → id, name, description, token, status (active/archived), owner_id
project_user → user_id, project_id, role_in_project (member/moderator), joined_at
activities → id, name, description, status (pending/in_progress/done/expired),
project_id, created_by_id, assigned_to_id, due_date
All relationships are managed with Eloquent — hasMany, belongsTo, belongsToMany — with eager loading on relevant endpoints to minimize queries.
A Laravel scheduled command runs automatically to expire overdue activities:
// Marks all activities as 'expired' where due_date < today and status != done
php artisan activities:expireRegistered in the Laravel scheduler to run daily.
All routes are prefixed with /api and protected with Sanctum middleware where required.
| Method | Endpoint | Access |
|---|---|---|
| POST | /register |
Public |
| POST | /login |
Public |
| POST | /logout |
Auth |
| Method | Endpoint | Access |
|---|---|---|
| GET | /me |
Auth |
| PATCH | /me |
Auth |
| DELETE | /me |
Auth |
| GET | /me/stats |
Auth |
| GET | /users |
Admin |
| GET | /users/{id} |
Admin |
| Method | Endpoint | Access |
|---|---|---|
| GET | /projects |
Auth |
| GET | /projects/my |
Auth |
| GET | /projects/{id} |
Auth |
| GET | /projects/{id}/users |
Auth |
| POST | /projects |
Admin |
| PATCH | /projects/{id} |
Auth |
| PATCH | /projects/{id}/status |
Auth |
| DELETE | /projects/{id} |
Auth |
| POST | /projects/join/{token} |
Auth |
| DELETE | /projects/{id}/leave |
Auth |
| Method | Endpoint | Access |
|---|---|---|
| GET | /activities |
Auth |
| GET | /activities/{id} |
Auth |
| POST | /activities |
Admin |
| PATCH | /activities/{id} |
Auth |
| DELETE | /activities/{id} |
Auth |
| POST | /activities/{id}/assign |
Auth |
| PATCH | /activities/{id}/complete |
Auth |
| PATCH | /activities/{id}/unassign |
Auth |
Activity listing supports optional filters:
GET /activities?status=pending
GET /activities?assigned_to_me=true
GET /activities?my_projects=true
GET /activities?project_status=active
- PHP 8.2+
- Composer
- Node.js 18+
- MySQL or PostgreSQL
# Clone the repository
git clone https://github.com/DavidEricson00/TeamUP.git
cd TeamUP/backend
# Install dependencies
composer install
# Configure environment
cp .env.example .env
php artisan key:generate
# Set up database in .env, then run migrations
php artisan migrate
# Start the server
php artisan serve
# (Optional) Run the scheduler manually
php artisan schedule:runcd frontend
# Install dependencies
npm install
# Configure API base URL in .env
VITE_API_URL=http://localhost:8000/api
# Start development server
npm run devTeamUP was built to:
- Deep dive into the Laravel ecosystem — Sanctum, Eloquent, Middleware, Scheduler, Resource Controllers
- Practice structuring a production-grade REST API with proper auth, validation, and role-based access
- Build a complete fullstack SPA integrating a Laravel backend with a React + TypeScript frontend
- Work with relational data modeling — pivot tables, eager loading, and complex query filters
- Handle real-world flows like project membership via invite tokens, activity assignment, and automated status expiration



