Complete Project Setup & CSS Styles
CSS Styles
1. Main App Styles (src/App.css)
/* Rural Learning Platform - Optimized for Low-end Devices */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f5f7fa;
color: #333;
line-height: 1.6;
}
.App {
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* Header Styles - Large buttons for rural users */
.app-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 1rem;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
max-width: 1200px;
margin: 0 auto;
}
.header-content h1 {
font-size: 1.5rem;
font-weight: 600;
}
.header-controls {
display: flex;
align-items: center;
gap: 1rem;
}
.logout-btn {
background: rgba(255,255,255,0.2);
border: none;
color: white;
padding: 0.5rem 1rem;
border-radius: 20px;
cursor: pointer;
font-weight: 500;
transition: background 0.3s;
min-height: 44px; /* Touch-friendly */
}
.logout-btn:hover {
background: rgba(255,255,255,0.3);
}
/* Main Content */
.app-main {
flex: 1;
padding: 1rem;
max-width: 1200px;
margin: 0 auto;
width: 100%;
}
/* Loading States */
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 200px;
gap: 1rem;
}
.loading-spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #667eea;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Responsive Design - Mobile First */
@media (max-width: 768px) {
.header-content {
flex-direction: column;
gap: 1rem;
}
.header-content h1 {
font-size: 1.25rem;
}
.app-main {
padding: 0.5rem;
}
}
/* High contrast mode for rural visibility */
@media (prefers-contrast: high) {
body {
background-color: #ffffff;
color: #000000;
}
.app-header {
background: #000000;
color: #ffffff;
}
}
2. Login Component Styles (src/components/auth/Login.css)
.login-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 80vh;
padding: 1rem;
}
.login-card {
background: white;
padding: 2rem;
border-radius: 10px;
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
width: 100%;
max-width: 400px;
}
.login-card h2 {
text-align: center;
margin-bottom: 1.5rem;
color: #333;
font-size: 1.5rem;
}
.login-card form {
display: flex;
flex-direction: column;
gap: 1rem;
}
.login-card input,
.login-card select {
padding: 1rem;
border: 2px solid #e1e5e9;
border-radius: 8px;
font-size: 1rem;
transition: border-color 0.3s;
min-height: 50px; /* Touch-friendly */
}
.login-card input:focus,
.login-card select:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.submit-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 1rem;
border-radius: 8px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: transform 0.2s;
min-height: 50px;
}
.submit-btn:hover:not(:disabled) {
transform: translateY(-1px);
}
.submit-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.toggle-btn {
background: none;
border: none;
color: #667eea;
text-decoration: underline;
cursor: pointer;
padding: 0.5rem;
margin-top: 1rem;
font-size: 0.9rem;
}
.error-message {
background: #ffe6e6;
color: #d32f2f;
padding: 0.75rem;
border-radius: 4px;
margin-bottom: 1rem;
border: 1px solid #ffcdd2;
text-align: center;
}
.demo-credentials {
margin-top: 1.5rem;
padding: 1rem;
background: #f8f9fa;
border-radius: 6px;
font-size: 0.85rem;
}
.demo-credentials h4 {
margin-bottom: 0.5rem;
color: #555;
}
.demo-credentials p {
margin: 0.25rem 0;
color: #666;
}
/* Mobile optimization */
@media (max-width: 480px) {
.login-card {
padding: 1.5rem;
margin: 0 0.5rem;
}
.login-card input,
.login-card select,
.submit-btn {
min-height: 55px; /* Larger touch targets */
font-size: 1.1rem;
}
}
3. Student Dashboard Styles (src/components/student/StudentDashboard.css)
.student-dashboard {
max-width: 1200px;
margin: 0 auto;
}
.dashboard-header {
margin-bottom: 2rem;
}
.dashboard-header h2 {
font-size: 1.8rem;
color: #333;
margin-bottom: 1rem;
}
.dashboard-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
margin-bottom: 1.5rem;
}
.stat-card {
background: white;
padding: 1.5rem;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
text-align: center;
border-left: 4px solid #667eea;
}
.stat-card h3 {
font-size: 2rem;
color: #667eea;
margin-bottom: 0.5rem;
}
.stat-card p {
color: #666;
font-weight: 500;
}
.dashboard-filters {
margin-bottom: 1.5rem;
}
.subject-filter {
padding: 0.75rem 1rem;
border: 2px solid #e1e5e9;
border-radius: 8px;
font-size: 1rem;
background: white;
min-width: 200px;
cursor: pointer;
}
.lessons-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
}
.lesson-card {
background: white;
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
transition: transform 0.3s, box-shadow 0.3s;
border: 1px solid #e1e5e9;
}
.lesson-card:hover {
transform: translateY(-2px);
box-shadow: 0 6px 25px rgba(0,0,0,0.15);
}
.lesson-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 1rem;
}
.lesson-header h3 {
font-size: 1.2rem;
color: #333;
margin-bottom: 0.5rem;
line-height: 1.4;
}
.subject-badge {
background: #667eea;
color: white;
padding: 0.25rem 0.75rem;
border-radius: 20px;
font-size: 0.8rem;
font-weight: 500;
white-space: nowrap;
}
.lesson-description {
color: #666;
margin-bottom: 1rem;
line-height: 1.5;
}
.lesson-progress {
margin-bottom: 1rem;
}
.progress-bar {
background: #e1e5e9;
height: 8px;
border-radius: 4px;
overflow: hidden;
margin-bottom: 0.5rem;
}
.progress-fill {
background: linear-gradient(90deg, #667eea, #764ba2);
height: 100%;
transition: width 0.3s ease;
}
.lesson-progress span {
font-size: 0.9rem;
color: #666;
font-weight: 500;
}
.start-lesson-btn {
display: block;
width: 100%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
text-decoration: none;
padding: 0.75rem 1rem;
border-radius: 8px;
text-align: center;
font-weight: 600;
transition: transform 0.2s;
min-height: 50px;
display: flex;
align-items: center;
justify-content: center;
}
.start-lesson-btn:hover {
transform: translateY(-1px);
color: white;
}
.no-lessons {
text-align: center;
padding: 3rem 1rem;
color: #666;
}
/* Mobile optimizations */
@media (max-width: 768px) {
.dashboard-stats {
grid-template-columns: 1fr;
}
.lessons-grid {
grid-template-columns: 1fr;
}
.lesson-header {
flex-direction: column;
align-items: flex-start;
gap: 0.5rem;
}
.dashboard-header h2 {
font-size: 1.5rem;
}
}
@media (max-width: 480px) {
.lesson-card {
padding: 1rem;
}
.start-lesson-btn {
min-height: 55px;
font-size: 1.1rem;
}
}
4. Setup Files
Package.json Scripts Addition
{
"scripts": {
"start": "concurrently \"npm run server\" \"npm run client\"",
"server": "cd server && node index.js",
"client": "react-scripts start",
"build": "react-scripts build && npm run build-server",
"build-server": "cd server && npm install --production",
"dev": "concurrently \"nodemon server/index.js\" \"react-scripts start\"",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
}
Environment Variables (.env)
# Development
REACT_APP_API_URL=http://localhost:5000/api
PORT=3000
# Production
REACT_APP_API_URL=/api
PWA Manifest (public/manifest.json)
{
"short_name": "Rural Learning",
"name": "Rural Learning Platform - Nabha",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#667eea",
"background_color": "#ffffff",
"categories": ["education", "productivity"],
"lang": "pa",
"orientation": "portrait"
}
Docker Setup (Dockerfile)
# Multi-stage build for production
FROM node:16-alpine as build
# Build frontend
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Production stage
FROM node:16-alpine
WORKDIR /app
# Copy server files
COPY server/ ./server/
COPY --from=build /app/build ./build
# Install server dependencies
WORKDIR /app/server
RUN npm ci --only=production
# Create database directory
RUN mkdir -p /app/data
EXPOSE 5000
CMD ["node", "index.js"]
Docker Compose (docker-compose.yml)
version: '3.8'
services:
rural-learning:
build: .
ports:
- "5000:5000"
volumes:
- ./data:/app/data
environment:
- NODE_ENV=production
- JWT_SECRET=your_jwt_secret_here
restart: unless-stopped
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- rural-learning
restart: unless-stopped
Quick Start Instructions
1. Development Setup
# Clone and setup
git clone <repository>
cd rural-learning-platform
# Install dependencies
npm install
cd server && npm install && cd ..
# Start development servers
npm run dev
2. Production Build
# Build for production
npm run build
# Deploy with Docker
docker-compose up -d
3. Test Accounts
Student: username student, password student123
Teacher: username teacher, password teacher123
4. Key Features Implemented
✅ Offline-first architecture with IndexedDB storage
✅ Multilingual support (Punjabi, Hindi, English)
✅ Progressive Web App capabilities
✅ Touch-optimized interface for rural users
✅ Teacher dashboard with student analytics
✅ Background sync for offline progress
✅ Responsive design for low-end devices
✅ Voice assistant integration ready
✅ Content management system
✅ Quiz and assessment tools
5. Performance Optimizations
Lazy loading of components and content
Service worker caching for offline use
Optimized bundle size for slow connections
IndexedDB for local storage
Efficient state management
Mobile-first responsive design
This complete codebase provides a fully functional, offline-capable digital learning platform
optimized for rural school students in Nabha, Punjab.