{"id":50103060,"url":"https://github.com/ayerna/afford","last_synced_at":"2026-05-23T08:35:16.879Z","repository":{"id":355156242,"uuid":"1227000576","full_name":"ayerna/afford","owner":"ayerna","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-02T06:17:48.000Z","size":3538,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-02T07:16:51.553Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ayerna.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-02T04:38:31.000Z","updated_at":"2026-05-02T06:17:52.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ayerna/afford","commit_stats":null,"previous_names":["ayerna/afford"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ayerna/afford","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayerna%2Fafford","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayerna%2Fafford/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayerna%2Fafford/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayerna%2Fafford/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ayerna","download_url":"https://codeload.github.com/ayerna/afford/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayerna%2Fafford/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33389226,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T04:15:53.637Z","status":"ssl_error","status_checked_at":"2026-05-23T04:15:53.242Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-23T08:35:16.150Z","updated_at":"2026-05-23T08:35:16.873Z","avatar_url":"https://github.com/ayerna.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Campus Notifications Systems\n\nA responsive React + TypeScript application for displaying campus notifications with priority ranking and filtering. This repository contains the **Stage 2 Frontend Implementation** of the Campus Notifications microservice.\n\n---\n\n## 📋 Project Overview\n\n### Stage 1: Backend API \u0026 Logging Middleware\n**✓ Implemented** - Production-ready Express.js API and centralized logging\n\n**[notification_app_be/](notification_app_be/)**:\n- Express.js REST API server on port 3001\n- JWT Bearer token authentication\n- Paginated notifications endpoints with filtering\n- Mock data (12 sample notifications)\n- Error handling and CORS support\n- `GET /notifications` - List all notifications\n- `POST /auth/token` - Generate JWT token\n- Full API documentation in [notification_app_be/README.md](notification_app_be/README.md)\n\n**[logging_middleware/](logging_middleware/)**:\n- Centralized request/response logging library\n- Multi-transport support (Console, File)\n- Color-coded log levels (DEBUG, INFO, WARN, ERROR)\n- Automatic file rotation with backup management\n- Structured log records with metadata\n- Express middleware integration ready\n- Full documentation in [logging_middleware/README.md](logging_middleware/README.md)\n\n### Stage 2: Frontend (React Application)\n**✓ Implemented** - Interactive web interface for browsing and managing notifications\n\nA responsive React + TypeScript application for displaying campus notifications with priority ranking and filtering.\n\n---\n\n## 🎯 Stage 2 Features\n\n### All Notifications View\n- **Paginated List**: Browse notifications with configurable page size (5, 8, 10, 15 per page)\n- **Type Filtering**: Filter by Placement, Result, or Event\n- **Navigation**: Previous/Next pagination controls\n- **Real-time Refresh**: Refresh button to fetch latest data\n\n### Priority Notifications View\n- **Top N Ranking**: Display top N notifications (configurable: 5, 10, 15, 20)\n- **Smart Sorting**: Automatic ranking by type and recency\n- **Priority-based Layout**: Placement items highlighted more prominently\n\n### General Features\n- **Viewed Tracking**: Mark notifications as viewed; persist state in localStorage\n- **Responsive Design**: Mobile-friendly (390px) and desktop (1024px+) layouts\n- **Material UI Theme**: Custom design system with teal and navy palette\n- **Error Handling**: Clear error states and retry capabilities\n- **Loading States**: Skeleton cards during data fetch\n\n### Priority Rules\n\nNotifications are ranked by type (highest to lowest):\n1. **Placement** (priority: 3) - Hiring announcements, placement drives\n2. **Result** (priority: 2) - Academic results, exam scores\n3. **Event** (priority: 1) - Campus events, festivals, workshops\n\nWithin the same priority, newer notifications appear first (latest timestamp first).\n\n---\n\n## 📷 Screenshots \u0026 Demo\n\n### Application Views\n\n**Main Dashboard**\n![Dashboard](screenshots/Dashboard.png)\n\n**All Notifications - 10 Per Page**\n![10 Per Page](screenshots/10%20page.png)\n\n**All Notifications - 5 Per Page**\n![5 Per Page](screenshots/5%20page.png)\n\n**Loading State - Fetching Notifications**\n![Loading State](screenshots/fetching%20notification.png)\n\n**Filter Controls \u0026 Options**\n![Filter Controls](screenshots/filtering%20options.png)\n\n**Marking Notification as Viewed**\n![Mark as Viewed](screenshots/marking%20as%20viewed.png)\n\n**Priority View - Top 10 Notifications**\n![Priority Top 10](screenshots/priority%20notification%2010.png)\n\n**Priority View - Top 5 Notifications**\n![Priority Top 5](screenshots/priority%20notification%205.png)\n\n**Filters in Action**\n![Filters in Action](screenshots/working%20of%20filters.png)\n\n---\n\n## 🏗️ Repository Structure\n\n```\nafford/\n├── notification_app_fe/          # Stage 2: Frontend React Application\n│   ├── src/\n│   │   ├── App.tsx              # Main component (443 lines)\n│   │   ├── types.ts             # TypeScript domain model\n│   │   ├── theme.ts             # Material UI customization\n│   │   ├── api/\n│   │   │   └── notifications.ts # API client (bearer token auth)\n│   │   ├── components/\n│   │   │   ├── NotificationCard.tsx\n│   │   │   ├── FeedSkeleton.tsx\n│   │   │   └── EmptyState.tsx\n│   │   └── utils/\n│   │       └── notifications.ts # Priority ranking algorithm\n│   ├── package.json\n│   ├── vite.config.ts\n│   └── README.md\n│\n├── notification_app_be/          # Stage 1: Backend Express API\n│   ├── src/\n│   │   ├── index.ts             # Express server\n│   │   ├── types.ts             # TypeScript interfaces\n│   │   ├── routes/\n│   │   │   ├── notifications.ts # Notification endpoints\n│   │   │   └── auth.ts          # Authentication endpoints\n│   │   ├── middleware/\n│   │   │   ├── auth.ts          # JWT verification\n│   │   │   └── errorHandler.ts  # Error handling\n│   │   └── data/\n│   │       └── mock.ts          # Mock notifications\n│   ├── package.json\n│   ├── tsconfig.json\n│   ├── .env.example\n│   └── README.md\n│\n├── logging_middleware/           # Stage 1: Centralized Logging\n│   ├── src/\n│   │   ├── index.ts             # Logger factory\n│   │   ├── types.ts             # Logger interfaces\n│   │   └── transports/\n│   │       ├── ConsoleTransport.ts\n│   │       └── FileTransport.ts\n│   ├── package.json\n│   ├── tsconfig.json\n│   ├── .env.example\n│   └── README.md\n│\n├── notification_system_design.md # Complete system documentation\n├── README.md                      # This file\n├── BUILD_VERIFICATION.md          # Build metrics and testing\n├── screenshots/                   # Application screenshots\n│   ├── README.md\n│   ├── desktop-all-notifications.png\n│   └── mobile-all-notifications.png\n└── .gitignore\n```\n\n---\n\n## 🚀 Getting Started\n\n### Option 1: Frontend Only (Stage 2)\n\n```bash\ncd notification_app_fe\nnpm install\nnpm run dev\n# Opens at http://localhost:3000\n```\n\nRequires `.env.local`:\n```\nVITE_NOTIFICATION_API_BASE=http://20.207.122.201/evaluation-service/notifications\nVITE_NOTIFICATION_API_TOKEN=eyJhbGci...\n```\n\n### Option 2: Full Stack (Stage 1 + Stage 2)\n\n**Terminal 1 - Start Backend**:\n```bash\ncd notification_app_be\nnpm install\nnpm run dev\n# Server running at http://localhost:3001\n```\n\n**Terminal 2 - Start Frontend**:\n```bash\ncd notification_app_fe\nnpm install\ncp .env.example .env.local\n# Edit .env.local to point to http://localhost:3001/notifications\nnpm run dev\n# Opens at http://localhost:3000\n```\n\n### Option 3: Backend Only (Stage 1)\n\n```bash\ncd notification_app_be\nnpm install\nnpm run dev\n# API available at http://localhost:3001\n```\n\nExample requests:\n```bash\n# Get token\ncurl -X POST http://localhost:3001/auth/token \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"username\": \"student\"}'\n\n# Fetch notifications\ncurl http://localhost:3001/notifications?page=1\u0026limit=10\n```\n\n---\n\n## 📚 Documentation\n\n| Document | Purpose |\n|----------|---------|\n| [notification_system_design.md](notification_system_design.md) | Complete architecture, implementation status, tech stack, data flow |\n| [notification_app_fe/README.md](notification_app_fe/README.md) | Frontend setup, features, API integration (Stage 2) |\n| [notification_app_be/README.md](notification_app_be/README.md) | Backend API setup, endpoints, authentication (Stage 1) |\n| [logging_middleware/README.md](logging_middleware/README.md) | Logging library usage, transports, configuration |\n| [BUILD_VERIFICATION.md](BUILD_VERIFICATION.md) | Build metrics, bundle size, performance results |\n| [screenshots/README.md](screenshots/README.md) | Screenshot guide, capture instructions, demo workflows |\n\n---\n\n## 📋 Prerequisites \u0026 Setup\n\n### Prerequisites\n\n- **Node.js 18+** and **npm 9+**\n- For external API: Valid evaluation service credentials\n- Modern browser (Chrome, Firefox, Safari, Edge)\n\n### Frontend Configuration\n\nTo use the external evaluation service API:\n\n```bash\ncd notification_app_fe\n\n# Register with evaluation service\ncurl -X POST http://20.207.122.201/evaluation-service/register \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"email\":\"your_email\",\n    \"name\":\"Your Name\",\n    \"rollNo\":\"YOUR_ROLL_NO\",\n    \"accessCode\":\"ACCESS_CODE\"\n  }'\n\n# Get authorization token\ncurl -X POST http://20.207.122.201/evaluation-service/auth \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"email\":\"your_email\",\n    \"rollNo\":\"YOUR_ROLL_NO\",\n    \"accessCode\":\"ACCESS_CODE\"\n  }'\n```\n\nThen configure `.env.local`:\n\n```env\nVITE_NOTIFICATION_API_BASE=http://20.207.122.201/evaluation-service/notifications\nVITE_NOTIFICATION_API_TOKEN=your_bearer_token\n```\n\n### Development Workflow\n\n#### Terminal 1: Backend (Optional)\n\n```bash\ncd notification_app_be\nnpm install\nnpm run dev\n# Backend running at http://localhost:3001\n```\n\n#### Terminal 2: Frontend\n\n```bash\ncd notification_app_fe\nnpm install\ncp .env.example .env.local\n# Edit .env.local with your API configuration\nnpm run dev\n# Frontend running at http://localhost:3000\n```\n\n### Production Build\n\n**Frontend:**\n```bash\ncd notification_app_fe\nnpm run build    # Outputs to dist/\nnpm run preview  # Test production build locally\n```\n\n**Backend:**\n```bash\ncd notification_app_be\nnpm run build    # Outputs to dist/\nnpm run start    # Start production server\n```\n\nBuild Output (Frontend):\n- Size: ~465 KB (uncompressed), ~144 KB (gzipped)\n- Modules: 927 transformed\n- Time: ~8.5 seconds\n\n---\n\n## 📁 Stage 2 Architecture\n\n### Folder Structure\n\n```\nnotification_app_fe/\n├── src/\n│   ├── api/                    # API client and HTTP logic\n│   │   └── notifications.ts    # Notification fetching with auth\n│   ├── components/             # Reusable React components\n│   │   ├── NotificationCard.tsx     # Individual notification display\n│   │   ├── FeedSkeleton.tsx        # Loading skeleton\n│   │   └── EmptyState.tsx          # Empty state messaging\n│   ├── utils/                  # Utility functions\n│   │   └── notifications.ts    # Sorting, filtering, formatting\n│   ├── types.ts                # TypeScript type definitions\n│   ├── theme.ts                # Material UI theme config\n│   ├── App.tsx                 # Main application component\n│   └── main.tsx                # React entry point\n├── index.html                  # HTML template\n├── package.json                # Dependencies and scripts\n├── tsconfig.json               # TypeScript config\n├── vite.config.ts              # Vite build config\n└── .env.example                # Environment variable template\n```\n\n### Component Hierarchy\n\n```\nApp\n├── AppBar (Header with refresh button)\n├── Hero Section (Stats: filter, page size, top N, viewed count)\n├── Tabs (All Notifications | Priority Notifications)\n│   ├── All Notifications Tab\n│   │   ├── Filters (Type, Page Size)\n│   │   ├── NotificationCard[] (Grid layout)\n│   │   └── Pagination (Previous/Next)\n│   └── Priority Notifications Tab\n│       └── NotificationCard[] (Top N cards)\n```\n\n### State Management\n\n**Server State** (React Hooks - `useState`, `useEffect`):\n- `pageRows`: Notifications from paginated API\n- `priorityRows`: All notifications for priority calculation\n- `loadingPage`: Fetch progress indicator\n- `pageError`: Error message display\n\n**UI State**:\n- `mode`: Active tab ('all' | 'priority')\n- `filterChoice`: Selected type filter\n- `page`: Current pagination page\n- `pageSize`: Rows per page\n- `topCount`: Number of top priorities to show\n\n**Local State** (localStorage):\n- `viewedIds`: Set of notification IDs marked as viewed\n- Key: `campus-notifications:viewed`\n\n### Data Flow\n\n```\nAPI Fetch (useEffect)\n    ↓\nAPI Response (json)\n    ↓\nDecorate (add rank, parse time, add viewed flag)\n    ↓\nSort (by priority, then by timestamp)\n    ↓\nSlice (Top N for priority view)\n    ↓\nRender (NotificationCard components)\n```\n\n## 💡 Recommendations for Stage 1\n\nIf implementing the Priority Inbox backend/script:\n\n1. **Language**: Suggest TypeScript/Node.js for consistency with frontend\n2. **Output**: Return paginated top N notifications with priority scores\n3. **Efficiency**: Use min-heap for continuous notification streams\n4. **Testing**: Verify sorting with mixed notification types\n5. **Documentation**: See `notification_system_design.md` for detailed requirements\n\n---\n\n## 🌐 Browser Compatibility\n\n- **Chrome/Edge**: 90+\n- **Firefox**: 88+\n- **Safari**: 14+\n- **Mobile**: iOS Safari 12+, Chrome Mobile 90+\n\n---\n\n## 📚 Additional Documentation\n\n- **Design Document**: [`notification_system_design.md`](notification_system_design.md) - System architecture and efficiency analysis\n- **Build Verification**: [`BUILD_VERIFICATION.md`](BUILD_VERIFICATION.md) - Build metrics and testing results\n\n---\n\n## 📝 License\n\nAcademic submission for evaluation purposes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fayerna%2Fafford","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fayerna%2Fafford","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fayerna%2Fafford/lists"}