{"id":38639452,"url":"https://github.com/arsanjani/url-shortener","last_synced_at":"2026-01-17T09:06:42.830Z","repository":{"id":181813847,"uuid":"308846843","full_name":"arsanjani/url-shortener","owner":"arsanjani","description":"ScissorLink is an advanced open-source URL shortener built with .NET 9 \u0026 React. Fast redirects, analytics, custom links, and a modern admin dashboard.","archived":false,"fork":false,"pushed_at":"2025-08-25T14:19:15.000Z","size":3981,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-25T15:26:37.298Z","etag":null,"topics":["aspnet-core","bitly-alternative","dotnet-9","entity-framework-core","link-analytics","link-shortener-api","link-tracking","material-ui-react","open-source-url-shortener","react","self-hosted","sql-server-database","typescript","url-shortener"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arsanjani.png","metadata":{"files":{"readme":"README-Admin.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2020-10-31T09:27:13.000Z","updated_at":"2025-08-25T14:16:56.000Z","dependencies_parsed_at":"2025-08-25T15:14:04.657Z","dependency_job_id":"db2e9bb5-6b72-4029-b63f-4cea806c9518","html_url":"https://github.com/arsanjani/url-shortener","commit_stats":null,"previous_names":["arsanjani/url-shortener"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/arsanjani/url-shortener","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsanjani%2Furl-shortener","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsanjani%2Furl-shortener/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsanjani%2Furl-shortener/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsanjani%2Furl-shortener/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arsanjani","download_url":"https://codeload.github.com/arsanjani/url-shortener/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsanjani%2Furl-shortener/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28504675,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T06:57:29.758Z","status":"ssl_error","status_checked_at":"2026-01-17T06:56:03.931Z","response_time":85,"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":["aspnet-core","bitly-alternative","dotnet-9","entity-framework-core","link-analytics","link-shortener-api","link-tracking","material-ui-react","open-source-url-shortener","react","self-hosted","sql-server-database","typescript","url-shortener"],"created_at":"2026-01-17T09:06:40.413Z","updated_at":"2026-01-17T09:06:42.195Z","avatar_url":"https://github.com/arsanjani.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# 🎨 ScissorLink Admin Interface\n\n[![React](https://img.shields.io/badge/React-18-61dafb?style=for-the-badge\u0026logo=react)](https://reactjs.org/)\n[![TypeScript](https://img.shields.io/badge/TypeScript-4.9-3178c6?style=for-the-badge\u0026logo=typescript)](https://www.typescriptlang.org/)\n[![Material-UI](https://img.shields.io/badge/Material--UI-5.15-0081cb?style=for-the-badge\u0026logo=mui)](https://mui.com/)\n[![Entity Framework](https://img.shields.io/badge/Entity_Framework-9.0-512bd4?style=for-the-badge\u0026logo=microsoft)](https://docs.microsoft.com/en-us/ef/)\n\n**🚀 Modern React admin interface for managing the ScissorLink URL shortener**\n\n*Beautiful, responsive, and powerful admin dashboard built with Material-UI*\n\n[🎯 Features](#-features-implemented) • [🏗️ Setup](#-setup-instructions) • [🔌 API](#-api-endpoints) • [🎨 UI Features](#-uiux-features)\n\n---\n\n\u003c/div\u003e\n\n![Admin Dashboard Preview](https://via.placeholder.com/800x400/1976d2/ffffff?text=ScissorLink+Admin+Dashboard)\n\n## 🎯 Features Implemented\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=\"50%\"\u003e\n\n### 🚀 **Backend Excellence (ASP.NET Core)**\n\n- ✅ **ORM Evolution** → Migrated from Dapper to Entity Framework Core\n- ✅ **Schema Harmony** → Updated models to match database schema perfectly\n- ✅ **RESTful APIs** → Complete admin API endpoints for CRUD operations\n- ✅ **Data Transfer** → Implemented proper DTOs for clean API communication\n- ✅ **CORS Ready** → Full support for React development workflow\n\n\u003c/td\u003e\n\u003ctd width=\"50%\"\u003e\n\n### ⚛️ **Frontend Power (React + TypeScript + Material-UI)**\n\n- ✅ **Modern Stack** → React 18 application with TypeScript\n- ✅ **Material Design** → Google Material Design implementation\n- ✅ **Smart Lists** → URL display with search and filtering capabilities\n- ✅ **Easy Creation** → Intuitive add new URL functionality\n- ✅ **Smart Testing** → Dynamic test buttons work on any domain\n- ✅ **Responsive UI** → Perfect on desktop, tablet, and mobile\n- ✅ **Live Updates** → Real-time status updates (publish/unpublish)\n- ✅ **Analytics View** → Comprehensive click analytics display\n- ✅ **Quick Actions** → One-click copy to clipboard functionality\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## Project Structure\n\n### Backend Structure\n```\nsrc/\n├── Controllers/\n│   ├── AdminController.cs      # Admin API endpoints\n│   └── ProcessController.cs    # URL redirection logic\n├── Data/\n│   └── ScissorLinkDbContext.cs # Entity Framework DbContext\n├── DTOs/                       # Data Transfer Objects\n│   ├── ShortLinkRequestDto.cs\n│   ├── ShortLinkResponseDto.cs\n│   └── ShortLinkDetailDto.cs\n├── Models/                     # Entity Framework models\n│   ├── DtoShortLink.cs\n│   └── DtoShortLinkDetail.cs\n└── Services/                   # Business logic\n    ├── ProcessService.cs\n    └── Interface/\n        └── IProcessService.cs\n```\n\n### Frontend Structure\n```\nclient/\n├── public/\n│   └── index.html\n├── src/\n│   ├── components/\n│   │   ├── AddShortLinkDialog.tsx\n│   │   └── ShortLinksList.tsx\n│   ├── pages/\n│   │   └── ShortLinksPage.tsx\n│   ├── services/\n│   │   └── apiService.ts\n│   ├── types/\n│   │   └── api.ts\n│   ├── App.tsx\n│   └── index.tsx\n└── package.json\n```\n\n## 🏗️ Setup Instructions\n\n\u003cdiv align=\"center\"\u003e\n\n### **⚡ Quick Setup Guide**\n\n*Get your admin interface running in minutes*\n\n\u003c/div\u003e\n\n### 📋 **Prerequisites**\n\n\u003cdiv align=\"center\"\u003e\n\n| Technology | Version Required | Status |\n|------------|------------------|--------|\n| 🔧 **.NET SDK** | 9.0+ | ![Required](https://img.shields.io/badge/Status-Required-red?style=flat-square) |\n| 📦 **Node.js** | 18.0+ | ![Required](https://img.shields.io/badge/Status-Required-red?style=flat-square) |\n| 🗄️ **SQL Server** | 2016+ | ![Required](https://img.shields.io/badge/Status-Required-red?style=flat-square) |\n\n*All configured in appsettings.json*\n\n\u003c/div\u003e\n\n### 🔧 **Backend Setup**\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eClick to expand backend setup steps\u003c/strong\u003e\u003c/summary\u003e\n\n**Step 1: Restore Dependencies**\n```bash\ncd src\ndotnet restore\n```\n\n**Step 2: Update Database (if needed)**\n```bash\ndotnet ef database update\n```\n\n**Step 3: Start the API**\n```bash\ndotnet run\n```\n\n🎉 **Backend ready at:** [`http://localhost:5000`](http://localhost:5000)\n\n\u003c/details\u003e\n\n### ⚛️ **Frontend Setup**\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eClick to expand frontend setup steps\u003c/strong\u003e\u003c/summary\u003e\n\n**Step 1: Install Dependencies**\n```bash\ncd client\nnpm install\n```\n\n**Step 2: Environment Configuration**\n```bash\n# Create .env file with:\nREACT_APP_API_URL=http://localhost:5000/api\n```\n\n**Step 3: Start Development Server**\n```bash\nnpm start\n```\n\n🎉 **Admin Interface ready at:** [`http://localhost:3000`](http://localhost:3000)\n\n\u003c/details\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n### **🚀 Pro Tip**\n\n*Use the automated scripts in the root directory for one-click setup!*\n\n```bash\n./start-dev.bat  # Windows\n./start-dev.ps1  # PowerShell\n```\n\n\u003c/div\u003e\n\n## API Endpoints\n\n### Admin API (`/api/admin`)\n- `GET /shortlinks` - Get all short links\n- `GET /shortlinks/{id}` - Get specific short link\n- `POST /shortlinks` - Create new short link\n- `PUT /shortlinks/{id}` - Update short link\n- `DELETE /shortlinks/{id}` - Delete short link\n- `POST /shortlinks/{id}/toggle-publish` - Toggle publish status\n\n### URL Redirection API\n- `GET /{token}` - Redirect to original URL and track analytics\n\n## Features\n\n### URL Management\n- **List View**: Display all shortened URLs with status, click count, and creation date\n- **Add New**: Create new short links with optional custom tokens\n- **Edit**: Update existing links (title, original URL, publish status)\n- **Delete**: Remove links with confirmation dialog\n- **Publish/Unpublish**: Toggle link availability\n\n### Dynamic Testing\n- **Test Links**: Each URL has a test button that dynamically uses the current domain\n- **Copy to Clipboard**: One-click copying of short URLs\n- **Real-time Preview**: See the short URL as you type the custom token\n\n### Analytics\n- **Click Tracking**: Display click count for each link\n- **Visitor Details**: Show recent clicks with country, OS, and browser information\n- **Date Tracking**: Creation and last edit timestamps\n\n### UI/UX Features\n- **Material Design**: Google Material Design standards throughout\n- **Responsive**: Works on desktop, tablet, and mobile\n- **Loading States**: Proper loading indicators for async operations\n- **Error Handling**: User-friendly error messages\n- **Notifications**: Success/error notifications for all actions\n\n## Database Schema\n\nThe application uses two main tables:\n- `ShortLink`: Main URL data\n- `ShortLinkDetail`: Click analytics and visitor information\n\n## Development Notes\n\n### Entity Framework Migration\nThe project has been fully migrated from Dapper to Entity Framework Core with:\n- Proper entity relationships\n- Automatic timestamp handling\n- Cascade delete for analytics data\n- Optimized queries with `Include()` statements\n\n### CORS Configuration\nCORS is configured to allow the React development server (`localhost:3000`) to access the API during development.\n\n### Error Handling\nBoth frontend and backend include comprehensive error handling:\n- API validation errors\n- Network connectivity issues\n- Database constraint violations\n- User-friendly error messages\n\n## Production Deployment\n\n### Backend\n1. Build the application:\n   ```bash\n   dotnet publish -c Release\n   ```\n\n2. Update connection strings for production\n3. Deploy to your preferred hosting platform\n\n### Frontend\n1. Build the React application:\n   ```bash\n   npm run build\n   ```\n\n2. Serve the built files from the `build/` directory\n3. Update the API URL environment variable for production\n\n## Security Considerations\n\n- Add authentication/authorization as needed\n- Implement rate limiting for API endpoints\n- Validate and sanitize all user inputs\n- Use HTTPS in production\n- Consider implementing API keys or JWT tokens\n\n## Future Enhancements\n\n- User authentication and role-based access\n- Bulk operations (import/export)\n- Advanced analytics dashboard\n- Link expiration dates\n- Custom domains support\n- QR code generation\n- Link categories/tags\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farsanjani%2Furl-shortener","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farsanjani%2Furl-shortener","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farsanjani%2Furl-shortener/lists"}