Skip to content

Commit 4fce6ac

Browse files
committed
Merge branch 'main' into bugfix/RTY-260013
2 parents b166727 + e6c7f85 commit 4fce6ac

File tree

14 files changed

+301
-1306
lines changed

14 files changed

+301
-1306
lines changed

README.md

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,22 @@
11
# Tiny URL Generator
22

3-
> A modern, Bitly-style tiny URL web application built with FastAPI, optional MongoDB, and a sleek web UI.
3+
> A modern, Bitly-style tiny URL web application built with FastAPI & MongoDB
44
5-
![Python](https://img.shields.io/badge/Python-3.11-blue.svg)
6-
![FastAPI](https://img.shields.io/badge/FastAPI-Backend-teal.svg)
7-
![MongoDB](<https://img.shields.io/badge/Database-MongoDB%20(Optional)-green.svg>)
5+
![Python](https://img.shields.io/badge/Python-3.10-blue.svg)
6+
![MongoDB](https://img.shields.io/badge/Database-MongoDB-green.svg)
87
![License](https://img.shields.io/badge/License-MIT-yellow.svg)
98
![Status](https://img.shields.io/badge/Status-Active-success.svg)
109

1110
---
1211

1312
## Overview
1413

15-
Tiny URL is a sleek, fast, and modern URL shortening platform built using FastAPI with optional MongoDB persistence.
14+
**tiny URL** is a sleek, fast, and modern URL shortening platform built using **FastAPI**, and **MongoDB**.
1615
It converts long URLs into short, shareable links — just like Bitly.
1716

1817
The project supports:
1918

20-
- Web UI (FastAPI + Jinja templates)
21-
- REST API (FastAPI)
22-
- Offline Mode (No MongoDB required)
23-
24-
This project is designed with:
25-
26-
- Clean startup lifecycle (no racing configs)
27-
- Optional database dependency
28-
- Graceful degradation when MongoDB is unavailable
29-
30-
- QR code generation with auto folder creation
19+
- 🚀 **FastAPI REST API** (developers / integrations)
3120

3221
---
3322

@@ -40,12 +29,13 @@ This project is designed with:
4029
- Clean Bitly-style result card
4130
- Copy & share buttons
4231
- Download URL button
43-
- URL validation and sanitization
44-
- Fully responsive UI
45-
- Recent URLs page (when DB is available)
46-
- Visit count tracking (when DB is available)
47-
- QR image auto-generation with logo
48-
- Cache-accelerated redirects
32+
- Share URL
33+
- Copy button with animation
34+
- Smooth URL validation and sanitization
35+
- Auto Dark/Light Mode (saves preference)
36+
- Mobile-friendly QR Codes
37+
- Fully responsive design
38+
- Recent URLs page
4939

5040
### API & Developer Features
5141

@@ -84,7 +74,15 @@ def generate_code(length=6):
8474

8575
---
8676

87-
## Tech Stack
77+
| Layer | Technology |
78+
| ----------- | --------------------- |
79+
| API Backend | FastAPI |
80+
| Database | MongoDB |
81+
| Frontend | HTML, CSS, Vanilla JS |
82+
| API Server | Uvicorn |
83+
| Validation | Pydantic v2 |
84+
| CLI | Click |
85+
| Data | JSON |
8886

8987
| Layer | Technology |
9088
| ----------- | --------------------- |
@@ -336,16 +334,15 @@ poetry run uvicorn app.main:app --reload
336334

337335
Screenshots:
338336
Home Page:
339-
![home page](app/assets/images/home.png)
340-
![home dark mode](app/assets/images/home_dark.png)
341-
![home page](app/assets/images/valid.png)
342-
![home layout](app/assets/images/short_url.png)
343-
![recent](app/assets/images/recent.png)
337+
![home page](./assets/images/home.png)
338+
![home dark mode](./assets/images/home_dark.png)
339+
![home page](./assets/images/valid.png)
340+
![home layout](./assets/images/short_url.png)
341+
![recent](./assets/images/recent.png)
344342
tiny API Page:
345-
![API](app/assets/images/API_page.png)
346-
![API1](app/assets/images/api_page2.png)
347-
No DB Mode:
348-
![NO DB](app/assets/images/no-db.png)
343+
![API](./assets/images/API_page.png)
344+
![API1](./assets/images/api_page2.png)
345+
349346
📜License
350347

351348
[MIT](LICENSE)

app/static/qr/zSDrr0.png

40.1 KB
Loading

app/static/style.css

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ button {
3939
font-weight: 600;
4040
}
4141

42-
4342
.dark-theme h1 {
4443
background: linear-gradient(90deg, #ffffff, #dddddd, #ffffff);
4544
-webkit-background-clip: text;
@@ -100,10 +99,8 @@ button {
10099

101100
.input-field input {
102101
color: #000 !important;
103-
104102
}
105103

106-
107104
.dark-theme .input-field input {
108105
color: #fff !important;
109106
}
@@ -119,7 +116,6 @@ button {
119116
transition: background-color 9999s ease-in-out 0s;
120117
}
121118

122-
123119
.input-field input:-webkit-autofill {
124120
-webkit-text-fill-color: #000 !important;
125121
}
@@ -156,7 +152,6 @@ button {
156152
background: linear-gradient(180deg, #0b1220, #050b14);
157153
}
158154

159-
160155
footer {
161156
margin-top: 0;
162157
}
@@ -267,7 +262,6 @@ body.dark-theme {
267262
--muted: #9aa7a6;
268263
}
269264

270-
271265
.page {
272266
flex: 1;
273267
display: flex;
@@ -276,10 +270,8 @@ body.dark-theme {
276270
gap: 1rem;
277271
padding: 2rem;
278272
min-height: 80vh;
279-
280273
}
281274

282-
283275
.theme-toggle {
284276
background: transparent;
285277
border: none;
@@ -374,7 +366,7 @@ body.dark-theme {
374366
}
375367

376368
.short-actions {
377-
display:flex;
369+
display: flex;
378370
justify-content: center;
379371
align-items: center;
380372
gap: 8px;
@@ -383,7 +375,6 @@ body.dark-theme {
383375
background: linear-gradient(180deg, rgba(75, 194, 176, 0.06), rgba(94, 207, 255, 0.04));
384376
}
385377

386-
387378
.short-box input {
388379
align-items: center;
389380
padding: 10px;
@@ -436,12 +427,12 @@ body.dark-theme {
436427
}
437428

438429
.qr-block img {
439-
width: 160px;
440-
height: 160px;
430+
height: 15rem;
441431
align-items: center;
442-
border-radius: 12px;
432+
aspect-ratio: 1;
443433
box-shadow: 0 10px 20px rgba(10, 20, 30, 0.06);
444-
background: #fff;
434+
outline: 2px solid green;
435+
outline-offset: 4px;
445436
}
446437

447438
.download-qr {
@@ -502,16 +493,15 @@ body.dark-theme {
502493
}
503494

504495
footer {
505-
min-height: auto;
496+
min-height: auto;
506497
}
507498

508499
.app-footer {
509500
background: white;
510501
color: #e5e7eb;
511502
padding: 8px 10px;
512-
margin-top: auto;
503+
margin-top: auto;
513504
position: relative;
514-
515505
}
516506
.dark-theme .app-footer {
517507
background: linear-gradient(180deg, #0b1220, #050b14);
@@ -525,8 +515,6 @@ footer {
525515
flex-wrap: wrap;
526516
}
527517

528-
529-
530518
.footer-brand {
531519
max-width: 420px;
532520
}
@@ -590,7 +578,6 @@ footer {
590578
transform: translateY(-2px);
591579
}
592580

593-
594581
.footer-links {
595582
display: flex;
596583
gap: 80px;
@@ -614,7 +601,7 @@ footer {
614601
}
615602

616603
.footer-col a:hover {
617-
text-decoration: underline;
604+
text-decoration: underline;
618605
}
619606

620607
/* Bottom */
@@ -658,7 +645,6 @@ footer {
658645
overflow-x: auto;
659646
}
660647

661-
662648
.recent-table {
663649
width: 100%;
664650
border-collapse: collapse;
@@ -669,7 +655,7 @@ footer {
669655
.recent-table thead {
670656
background: rgb(0, 0, 0);
671657
}
672-
.recent-table th{
658+
.recent-table th {
673659
color: rgb(0, 0, 0);
674660
padding: 8px 14px;
675661
text-align: left;
@@ -726,7 +712,6 @@ td {
726712
font-weight: 700;
727713
}
728714

729-
730715
.original-url {
731716
color: #22c55e;
732717
word-break: break-all;
@@ -823,9 +808,8 @@ td {
823808
}
824809
.info-box {
825810
margin-bottom: 15px;
826-
padding: 10px;
827-
color: #0e34f6;
828-
border-radius: 8px;
829-
font-weight: 700;
830-
831-
}
811+
padding: 10px;
812+
color: #0e34f6;
813+
border-radius: 8px;
814+
font-weight: 700;
815+
}

0 commit comments

Comments
 (0)