Spaces:
Running
Running
AdsurKasur commited on
Commit ·
7adacf8
1
Parent(s): a79c093
Add donation modal with payment platforms and cryptocurrency support
Browse files- .gitignore +4 -1
- ai-context.md +45 -10
- static/css/components.css +377 -0
- static/js/app.js +118 -0
- templates/index.html +229 -0
.gitignore
CHANGED
|
@@ -30,4 +30,7 @@ Thumbs.db
|
|
| 30 |
*.log
|
| 31 |
|
| 32 |
# AI generated files
|
| 33 |
-
ai-context.md
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
*.log
|
| 31 |
|
| 32 |
# AI generated files
|
| 33 |
+
ai-context.md
|
| 34 |
+
|
| 35 |
+
# Reference
|
| 36 |
+
reference/
|
ai-context.md
CHANGED
|
@@ -2,23 +2,33 @@
|
|
| 2 |
|
| 3 |
## Current Task Status
|
| 4 |
- **Phase**: Complete
|
| 5 |
-
- **Task**:
|
| 6 |
-
- **Last Updated**: 2025-12-
|
| 7 |
|
| 8 |
## File Context
|
| 9 |
| File Path | Status | Purpose | Notes |
|
| 10 |
|-----------|---------|---------|-------|
|
| 11 |
-
| `app.py` |
|
| 12 |
-
| `templates/index.html` |
|
| 13 |
-
| `static/css/base.css` |
|
| 14 |
-
| `static/css/components.css` |
|
| 15 |
-
| `static/css/layout.css` |
|
| 16 |
-
| `static/js/app.js` |
|
| 17 |
-
| `
|
| 18 |
-
| `Dockerfile` | unchanged | Container config | Python 3.9-slim, port 7860 (HF Spaces standard)
|
| 19 |
|
| 20 |
## Workflow History
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
### Phase 1: Project Restructuring (Completed)
|
| 23 |
- **Study**: Analyzed project structure, researched HF Spaces requirements
|
| 24 |
- **Propose**: Presented 3 options, recommended clean separation approach
|
|
@@ -37,6 +47,31 @@
|
|
| 37 |
|
| 38 |
## Implementation Summary
|
| 39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
### Phase 2 Changes Made
|
| 41 |
|
| 42 |
1. **Modern UI Design**:
|
|
|
|
| 2 |
|
| 3 |
## Current Task Status
|
| 4 |
- **Phase**: Complete
|
| 5 |
+
- **Task**: Donation Modal Implementation
|
| 6 |
+
- **Last Updated**: 2025-12-30
|
| 7 |
|
| 8 |
## File Context
|
| 9 |
| File Path | Status | Purpose | Notes |
|
| 10 |
|-----------|---------|---------|-------|
|
| 11 |
+
| `app.py` | unchanged | Flask application | Main backend
|
| 12 |
+
| `templates/index.html` | modified | HTML template | Added donation modal and trigger button
|
| 13 |
+
| `static/css/base.css` | unchanged | Core styles | Modern design system
|
| 14 |
+
| `static/css/components.css` | modified | UI components | Added donation modal styles
|
| 15 |
+
| `static/css/layout.css` | unchanged | Layout styles | Main layout
|
| 16 |
+
| `static/js/app.js` | modified | JavaScript logic | Added donation modal functionality
|
| 17 |
+
| `reference/donation-dialog.tsx` | reference | React donation dialog | Used as reference for implementation
|
|
|
|
| 18 |
|
| 19 |
## Workflow History
|
| 20 |
|
| 21 |
+
### Phase 3: Donation Modal (Completed)
|
| 22 |
+
- **Study**: Analyzed reference donation-dialog.tsx from React/Next.js project
|
| 23 |
+
- **Study**: Reviewed current project CSS patterns (colors, spacing, shadows)
|
| 24 |
+
- **Implement**:
|
| 25 |
+
- Added donation modal CSS styles matching project design system
|
| 26 |
+
- Added modal HTML with payment platforms (Trakteer, Ko-fi)
|
| 27 |
+
- Added cryptocurrency section (Bitcoin, EVM, Solana, Sui)
|
| 28 |
+
- Added copy-to-clipboard functionality with visual feedback
|
| 29 |
+
- Added "Support Me" button in footer to trigger modal
|
| 30 |
+
- Modal features: backdrop blur, smooth animations, responsive design
|
| 31 |
+
|
| 32 |
### Phase 1: Project Restructuring (Completed)
|
| 33 |
- **Study**: Analyzed project structure, researched HF Spaces requirements
|
| 34 |
- **Propose**: Presented 3 options, recommended clean separation approach
|
|
|
|
| 47 |
|
| 48 |
## Implementation Summary
|
| 49 |
|
| 50 |
+
### Phase 3 Changes Made
|
| 51 |
+
|
| 52 |
+
1. **Donation Modal Features**:
|
| 53 |
+
- Full-screen overlay with backdrop blur
|
| 54 |
+
- Smooth open/close animations
|
| 55 |
+
- Close via X button, overlay click, or Escape key
|
| 56 |
+
- Scrollable content for smaller screens
|
| 57 |
+
- Responsive design for mobile
|
| 58 |
+
|
| 59 |
+
2. **Payment Platforms Section**:
|
| 60 |
+
- Trakteer link (trakteer.id/adsurkasur)
|
| 61 |
+
- Ko-fi link (ko-fi.com/adsurkasur)
|
| 62 |
+
- External link icons indicating new tab behavior
|
| 63 |
+
|
| 64 |
+
3. **Cryptocurrency Section**:
|
| 65 |
+
- Bitcoin address with copy functionality
|
| 66 |
+
- EVM (Ethereum/BSC) address with copy functionality
|
| 67 |
+
- Solana address with copy functionality
|
| 68 |
+
- Sui address with copy functionality
|
| 69 |
+
- Visual feedback: copy icon changes to checkmark, "Copied!" badge appears
|
| 70 |
+
|
| 71 |
+
4. **Footer Enhancement**:
|
| 72 |
+
- Added "Support Me" button with heart icon
|
| 73 |
+
- Button styled to match footer's semi-transparent theme
|
| 74 |
+
|
| 75 |
### Phase 2 Changes Made
|
| 76 |
|
| 77 |
1. **Modern UI Design**:
|
static/css/components.css
CHANGED
|
@@ -352,4 +352,381 @@ input[type="file"] {
|
|
| 352 |
gap: var(--space-3);
|
| 353 |
justify-content: center;
|
| 354 |
flex-wrap: wrap;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 355 |
}
|
|
|
|
| 352 |
gap: var(--space-3);
|
| 353 |
justify-content: center;
|
| 354 |
flex-wrap: wrap;
|
| 355 |
+
}
|
| 356 |
+
|
| 357 |
+
/* ========================================
|
| 358 |
+
DONATION MODAL
|
| 359 |
+
======================================== */
|
| 360 |
+
|
| 361 |
+
/* Modal Overlay */
|
| 362 |
+
.modal-overlay {
|
| 363 |
+
position: fixed;
|
| 364 |
+
inset: 0;
|
| 365 |
+
background: rgba(0, 0, 0, 0.5);
|
| 366 |
+
backdrop-filter: blur(4px);
|
| 367 |
+
z-index: 1000;
|
| 368 |
+
display: flex;
|
| 369 |
+
align-items: center;
|
| 370 |
+
justify-content: center;
|
| 371 |
+
padding: var(--space-4);
|
| 372 |
+
opacity: 0;
|
| 373 |
+
visibility: hidden;
|
| 374 |
+
transition: all var(--duration-normal) var(--ease-out);
|
| 375 |
+
}
|
| 376 |
+
|
| 377 |
+
.modal-overlay.visible {
|
| 378 |
+
opacity: 1;
|
| 379 |
+
visibility: visible;
|
| 380 |
+
}
|
| 381 |
+
|
| 382 |
+
/* Modal Container */
|
| 383 |
+
.modal-container {
|
| 384 |
+
background: var(--color-white);
|
| 385 |
+
border-radius: var(--radius-xl);
|
| 386 |
+
box-shadow: var(--shadow-xl);
|
| 387 |
+
width: 100%;
|
| 388 |
+
max-width: 480px;
|
| 389 |
+
max-height: 90vh;
|
| 390 |
+
display: flex;
|
| 391 |
+
flex-direction: column;
|
| 392 |
+
transform: scale(0.95) translateY(20px);
|
| 393 |
+
transition: transform var(--duration-normal) var(--ease-out);
|
| 394 |
+
overflow: hidden;
|
| 395 |
+
}
|
| 396 |
+
|
| 397 |
+
.modal-overlay.visible .modal-container {
|
| 398 |
+
transform: scale(1) translateY(0);
|
| 399 |
+
}
|
| 400 |
+
|
| 401 |
+
/* Modal Header */
|
| 402 |
+
.modal-header {
|
| 403 |
+
display: flex;
|
| 404 |
+
align-items: center;
|
| 405 |
+
justify-content: space-between;
|
| 406 |
+
padding: var(--space-5) var(--space-6);
|
| 407 |
+
border-bottom: 1px solid var(--color-gray-100);
|
| 408 |
+
background: var(--color-white);
|
| 409 |
+
flex-shrink: 0;
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
.modal-title {
|
| 413 |
+
display: flex;
|
| 414 |
+
align-items: center;
|
| 415 |
+
gap: var(--space-2);
|
| 416 |
+
font-size: 1.125rem;
|
| 417 |
+
font-weight: 600;
|
| 418 |
+
color: var(--color-gray-800);
|
| 419 |
+
}
|
| 420 |
+
|
| 421 |
+
.modal-title svg {
|
| 422 |
+
width: 20px;
|
| 423 |
+
height: 20px;
|
| 424 |
+
color: #ef4444;
|
| 425 |
+
}
|
| 426 |
+
|
| 427 |
+
.modal-close {
|
| 428 |
+
display: flex;
|
| 429 |
+
align-items: center;
|
| 430 |
+
justify-content: center;
|
| 431 |
+
width: 32px;
|
| 432 |
+
height: 32px;
|
| 433 |
+
background: transparent;
|
| 434 |
+
border: none;
|
| 435 |
+
border-radius: var(--radius-sm);
|
| 436 |
+
color: var(--color-gray-400);
|
| 437 |
+
cursor: pointer;
|
| 438 |
+
transition: all var(--duration-fast) var(--ease-out);
|
| 439 |
+
}
|
| 440 |
+
|
| 441 |
+
.modal-close:hover {
|
| 442 |
+
background: var(--color-gray-100);
|
| 443 |
+
color: var(--color-gray-600);
|
| 444 |
+
}
|
| 445 |
+
|
| 446 |
+
.modal-close svg {
|
| 447 |
+
width: 18px;
|
| 448 |
+
height: 18px;
|
| 449 |
+
}
|
| 450 |
+
|
| 451 |
+
/* Modal Body */
|
| 452 |
+
.modal-body {
|
| 453 |
+
padding: var(--space-6);
|
| 454 |
+
overflow-y: auto;
|
| 455 |
+
flex: 1;
|
| 456 |
+
}
|
| 457 |
+
|
| 458 |
+
.modal-description {
|
| 459 |
+
text-align: center;
|
| 460 |
+
color: var(--color-gray-500);
|
| 461 |
+
font-size: 0.9375rem;
|
| 462 |
+
margin-bottom: var(--space-6);
|
| 463 |
+
line-height: 1.6;
|
| 464 |
+
}
|
| 465 |
+
|
| 466 |
+
/* Donation Section */
|
| 467 |
+
.donation-section {
|
| 468 |
+
margin-bottom: var(--space-6);
|
| 469 |
+
}
|
| 470 |
+
|
| 471 |
+
.donation-section:last-child {
|
| 472 |
+
margin-bottom: 0;
|
| 473 |
+
}
|
| 474 |
+
|
| 475 |
+
.donation-section-title {
|
| 476 |
+
display: flex;
|
| 477 |
+
align-items: center;
|
| 478 |
+
gap: var(--space-2);
|
| 479 |
+
font-size: 0.9375rem;
|
| 480 |
+
font-weight: 600;
|
| 481 |
+
color: var(--color-gray-700);
|
| 482 |
+
margin-bottom: var(--space-3);
|
| 483 |
+
}
|
| 484 |
+
|
| 485 |
+
.donation-section-title svg {
|
| 486 |
+
width: 18px;
|
| 487 |
+
height: 18px;
|
| 488 |
+
color: var(--color-gray-500);
|
| 489 |
+
}
|
| 490 |
+
|
| 491 |
+
/* Donation Card */
|
| 492 |
+
.donation-card {
|
| 493 |
+
display: flex;
|
| 494 |
+
align-items: center;
|
| 495 |
+
justify-content: space-between;
|
| 496 |
+
padding: var(--space-4);
|
| 497 |
+
background: var(--color-gray-50);
|
| 498 |
+
border: 1.5px solid var(--color-gray-100);
|
| 499 |
+
border-radius: var(--radius-md);
|
| 500 |
+
margin-bottom: var(--space-3);
|
| 501 |
+
cursor: pointer;
|
| 502 |
+
text-decoration: none;
|
| 503 |
+
color: inherit;
|
| 504 |
+
transition: all var(--duration-fast) var(--ease-out);
|
| 505 |
+
}
|
| 506 |
+
|
| 507 |
+
.donation-card:last-child {
|
| 508 |
+
margin-bottom: 0;
|
| 509 |
+
}
|
| 510 |
+
|
| 511 |
+
.donation-card:hover {
|
| 512 |
+
background: var(--color-white);
|
| 513 |
+
border-color: var(--color-primary-light);
|
| 514 |
+
transform: translateY(-2px);
|
| 515 |
+
box-shadow: var(--shadow-md);
|
| 516 |
+
}
|
| 517 |
+
|
| 518 |
+
.donation-card-content {
|
| 519 |
+
display: flex;
|
| 520 |
+
align-items: center;
|
| 521 |
+
gap: var(--space-3);
|
| 522 |
+
flex: 1;
|
| 523 |
+
min-width: 0;
|
| 524 |
+
}
|
| 525 |
+
|
| 526 |
+
.donation-icon {
|
| 527 |
+
display: flex;
|
| 528 |
+
align-items: center;
|
| 529 |
+
justify-content: center;
|
| 530 |
+
width: 40px;
|
| 531 |
+
height: 40px;
|
| 532 |
+
background: rgba(99, 102, 241, 0.1);
|
| 533 |
+
border-radius: var(--radius-md);
|
| 534 |
+
flex-shrink: 0;
|
| 535 |
+
transition: background var(--duration-fast) var(--ease-out);
|
| 536 |
+
}
|
| 537 |
+
|
| 538 |
+
.donation-card:hover .donation-icon {
|
| 539 |
+
background: rgba(99, 102, 241, 0.15);
|
| 540 |
+
}
|
| 541 |
+
|
| 542 |
+
.donation-icon svg {
|
| 543 |
+
width: 20px;
|
| 544 |
+
height: 20px;
|
| 545 |
+
}
|
| 546 |
+
|
| 547 |
+
.donation-icon.bitcoin { color: #f7931a; }
|
| 548 |
+
.donation-icon.ethereum { color: #627eea; }
|
| 549 |
+
.donation-icon.sui { color: #4da2ff; }
|
| 550 |
+
.donation-icon.kofi { color: #ff5e5b; }
|
| 551 |
+
.donation-icon.trakteer { color: #be1e2d; }
|
| 552 |
+
.donation-icon.qris { color: var(--color-primary); }
|
| 553 |
+
|
| 554 |
+
.donation-info {
|
| 555 |
+
flex: 1;
|
| 556 |
+
min-width: 0;
|
| 557 |
+
}
|
| 558 |
+
|
| 559 |
+
.donation-name {
|
| 560 |
+
font-weight: 500;
|
| 561 |
+
color: var(--color-gray-800);
|
| 562 |
+
margin-bottom: 2px;
|
| 563 |
+
}
|
| 564 |
+
|
| 565 |
+
.donation-label {
|
| 566 |
+
font-size: 0.8125rem;
|
| 567 |
+
color: var(--color-gray-400);
|
| 568 |
+
}
|
| 569 |
+
|
| 570 |
+
.donation-address {
|
| 571 |
+
font-family: var(--font-mono);
|
| 572 |
+
font-size: 0.75rem;
|
| 573 |
+
color: var(--color-gray-400);
|
| 574 |
+
word-break: break-all;
|
| 575 |
+
line-height: 1.4;
|
| 576 |
+
}
|
| 577 |
+
|
| 578 |
+
.donation-action {
|
| 579 |
+
display: flex;
|
| 580 |
+
align-items: center;
|
| 581 |
+
justify-content: center;
|
| 582 |
+
width: 32px;
|
| 583 |
+
height: 32px;
|
| 584 |
+
color: var(--color-gray-400);
|
| 585 |
+
flex-shrink: 0;
|
| 586 |
+
transition: color var(--duration-fast) var(--ease-out);
|
| 587 |
+
}
|
| 588 |
+
|
| 589 |
+
.donation-card:hover .donation-action {
|
| 590 |
+
color: var(--color-primary);
|
| 591 |
+
}
|
| 592 |
+
|
| 593 |
+
.donation-action svg {
|
| 594 |
+
width: 16px;
|
| 595 |
+
height: 16px;
|
| 596 |
+
}
|
| 597 |
+
|
| 598 |
+
/* Copy Badge */
|
| 599 |
+
.copy-badge {
|
| 600 |
+
display: inline-flex;
|
| 601 |
+
align-items: center;
|
| 602 |
+
gap: var(--space-1);
|
| 603 |
+
padding: 2px var(--space-2);
|
| 604 |
+
background: rgba(34, 197, 94, 0.1);
|
| 605 |
+
color: var(--color-success);
|
| 606 |
+
border-radius: var(--radius-sm);
|
| 607 |
+
font-size: 0.6875rem;
|
| 608 |
+
font-weight: 600;
|
| 609 |
+
margin-left: var(--space-2);
|
| 610 |
+
animation: fadeInScale 0.2s var(--ease-out);
|
| 611 |
+
}
|
| 612 |
+
|
| 613 |
+
@keyframes fadeInScale {
|
| 614 |
+
from {
|
| 615 |
+
opacity: 0;
|
| 616 |
+
transform: scale(0.8);
|
| 617 |
+
}
|
| 618 |
+
to {
|
| 619 |
+
opacity: 1;
|
| 620 |
+
transform: scale(1);
|
| 621 |
+
}
|
| 622 |
+
}
|
| 623 |
+
|
| 624 |
+
/* Thank You Message */
|
| 625 |
+
.modal-thank-you {
|
| 626 |
+
text-align: center;
|
| 627 |
+
padding: var(--space-4);
|
| 628 |
+
color: var(--color-gray-500);
|
| 629 |
+
font-size: 0.875rem;
|
| 630 |
+
}
|
| 631 |
+
|
| 632 |
+
/* Donation Button in Footer */
|
| 633 |
+
.btn-donate {
|
| 634 |
+
display: inline-flex;
|
| 635 |
+
align-items: center;
|
| 636 |
+
justify-content: center;
|
| 637 |
+
gap: var(--space-2);
|
| 638 |
+
padding: var(--space-3) var(--space-5);
|
| 639 |
+
background: rgba(255, 255, 255, 0.15);
|
| 640 |
+
color: var(--color-white);
|
| 641 |
+
border: 1.5px solid rgba(255, 255, 255, 0.3);
|
| 642 |
+
border-radius: var(--radius-md);
|
| 643 |
+
font-size: 0.875rem;
|
| 644 |
+
font-weight: 500;
|
| 645 |
+
font-family: inherit;
|
| 646 |
+
cursor: pointer;
|
| 647 |
+
transition: all var(--duration-fast) var(--ease-out);
|
| 648 |
+
margin-bottom: var(--space-5);
|
| 649 |
+
}
|
| 650 |
+
|
| 651 |
+
.btn-donate:hover {
|
| 652 |
+
background: rgba(255, 255, 255, 0.25);
|
| 653 |
+
border-color: rgba(255, 255, 255, 0.5);
|
| 654 |
+
transform: translateY(-2px);
|
| 655 |
+
}
|
| 656 |
+
|
| 657 |
+
.btn-donate svg {
|
| 658 |
+
width: 16px;
|
| 659 |
+
height: 16px;
|
| 660 |
+
}
|
| 661 |
+
|
| 662 |
+
/* QRIS Modal */
|
| 663 |
+
#qris-modal {
|
| 664 |
+
z-index: 1001;
|
| 665 |
+
}
|
| 666 |
+
|
| 667 |
+
.qris-modal-container {
|
| 668 |
+
max-width: 400px;
|
| 669 |
+
}
|
| 670 |
+
|
| 671 |
+
.qris-modal-body {
|
| 672 |
+
display: flex;
|
| 673 |
+
flex-direction: column;
|
| 674 |
+
align-items: center;
|
| 675 |
+
padding: var(--space-6);
|
| 676 |
+
}
|
| 677 |
+
|
| 678 |
+
.qris-image {
|
| 679 |
+
width: 100%;
|
| 680 |
+
max-width: 320px;
|
| 681 |
+
height: auto;
|
| 682 |
+
border-radius: var(--radius-lg);
|
| 683 |
+
box-shadow: var(--shadow-lg);
|
| 684 |
+
margin-bottom: var(--space-6);
|
| 685 |
+
}
|
| 686 |
+
|
| 687 |
+
.btn-qris-download {
|
| 688 |
+
display: inline-flex;
|
| 689 |
+
align-items: center;
|
| 690 |
+
justify-content: center;
|
| 691 |
+
gap: var(--space-2);
|
| 692 |
+
padding: var(--space-3) var(--space-6);
|
| 693 |
+
background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-accent) 100%);
|
| 694 |
+
color: var(--color-white);
|
| 695 |
+
border: none;
|
| 696 |
+
border-radius: var(--radius-md);
|
| 697 |
+
font-size: 0.9375rem;
|
| 698 |
+
font-weight: 500;
|
| 699 |
+
font-family: inherit;
|
| 700 |
+
text-decoration: none;
|
| 701 |
+
cursor: pointer;
|
| 702 |
+
transition: all var(--duration-fast) var(--ease-out);
|
| 703 |
+
}
|
| 704 |
+
|
| 705 |
+
.btn-qris-download:hover {
|
| 706 |
+
transform: translateY(-2px);
|
| 707 |
+
box-shadow: 0 8px 24px rgba(99, 102, 241, 0.35);
|
| 708 |
+
}
|
| 709 |
+
|
| 710 |
+
.btn-qris-download svg {
|
| 711 |
+
width: 18px;
|
| 712 |
+
height: 18px;
|
| 713 |
+
}
|
| 714 |
+
|
| 715 |
+
/* Responsive Modal */
|
| 716 |
+
@media (max-width: 640px) {
|
| 717 |
+
.modal-container {
|
| 718 |
+
max-height: 85vh;
|
| 719 |
+
}
|
| 720 |
+
|
| 721 |
+
.modal-body {
|
| 722 |
+
padding: var(--space-4);
|
| 723 |
+
}
|
| 724 |
+
|
| 725 |
+
.donation-address {
|
| 726 |
+
font-size: 0.6875rem;
|
| 727 |
+
}
|
| 728 |
+
|
| 729 |
+
.qris-image {
|
| 730 |
+
max-width: 280px;
|
| 731 |
+
}
|
| 732 |
}
|
static/js/app.js
CHANGED
|
@@ -8,6 +8,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
| 8 |
|
| 9 |
initFileUpload();
|
| 10 |
initFormSubmission();
|
|
|
|
| 11 |
clearQRResult();
|
| 12 |
});
|
| 13 |
|
|
@@ -221,4 +222,121 @@ function escapeHtml(text) {
|
|
| 221 |
const div = document.createElement('div');
|
| 222 |
div.textContent = text;
|
| 223 |
return div.innerHTML;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
}
|
|
|
|
| 8 |
|
| 9 |
initFileUpload();
|
| 10 |
initFormSubmission();
|
| 11 |
+
initDonationModal();
|
| 12 |
clearQRResult();
|
| 13 |
});
|
| 14 |
|
|
|
|
| 222 |
const div = document.createElement('div');
|
| 223 |
div.textContent = text;
|
| 224 |
return div.innerHTML;
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
// Donation Modal
|
| 228 |
+
function initDonationModal() {
|
| 229 |
+
const modal = document.getElementById('donation-modal');
|
| 230 |
+
const openBtn = document.getElementById('donate-btn');
|
| 231 |
+
const closeBtn = document.getElementById('modal-close');
|
| 232 |
+
|
| 233 |
+
// QRIS Modal
|
| 234 |
+
const qrisModal = document.getElementById('qris-modal');
|
| 235 |
+
const qrisCard = document.getElementById('qris-card');
|
| 236 |
+
const qrisCloseBtn = document.getElementById('qris-modal-close');
|
| 237 |
+
|
| 238 |
+
if (!modal || !openBtn) return;
|
| 239 |
+
|
| 240 |
+
// Open donation modal
|
| 241 |
+
openBtn.addEventListener('click', () => {
|
| 242 |
+
modal.classList.add('visible');
|
| 243 |
+
document.body.style.overflow = 'hidden';
|
| 244 |
+
});
|
| 245 |
+
|
| 246 |
+
// Close donation modal
|
| 247 |
+
function closeModal() {
|
| 248 |
+
modal.classList.remove('visible');
|
| 249 |
+
document.body.style.overflow = '';
|
| 250 |
+
}
|
| 251 |
+
|
| 252 |
+
closeBtn.addEventListener('click', closeModal);
|
| 253 |
+
|
| 254 |
+
// Close on overlay click
|
| 255 |
+
modal.addEventListener('click', (e) => {
|
| 256 |
+
if (e.target === modal) {
|
| 257 |
+
closeModal();
|
| 258 |
+
}
|
| 259 |
+
});
|
| 260 |
+
|
| 261 |
+
// QRIS Modal handlers
|
| 262 |
+
if (qrisCard && qrisModal) {
|
| 263 |
+
qrisCard.addEventListener('click', () => {
|
| 264 |
+
qrisModal.classList.add('visible');
|
| 265 |
+
});
|
| 266 |
+
|
| 267 |
+
function closeQrisModal() {
|
| 268 |
+
qrisModal.classList.remove('visible');
|
| 269 |
+
}
|
| 270 |
+
|
| 271 |
+
qrisCloseBtn.addEventListener('click', closeQrisModal);
|
| 272 |
+
|
| 273 |
+
qrisModal.addEventListener('click', (e) => {
|
| 274 |
+
if (e.target === qrisModal) {
|
| 275 |
+
closeQrisModal();
|
| 276 |
+
}
|
| 277 |
+
});
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
// Close on Escape key
|
| 281 |
+
document.addEventListener('keydown', (e) => {
|
| 282 |
+
if (e.key === 'Escape') {
|
| 283 |
+
if (qrisModal && qrisModal.classList.contains('visible')) {
|
| 284 |
+
qrisModal.classList.remove('visible');
|
| 285 |
+
} else if (modal.classList.contains('visible')) {
|
| 286 |
+
closeModal();
|
| 287 |
+
}
|
| 288 |
+
}
|
| 289 |
+
});
|
| 290 |
+
|
| 291 |
+
// Copy crypto addresses
|
| 292 |
+
const cryptoCards = document.querySelectorAll('.donation-card[data-crypto]');
|
| 293 |
+
cryptoCards.forEach(card => {
|
| 294 |
+
card.addEventListener('click', () => {
|
| 295 |
+
const address = card.dataset.address;
|
| 296 |
+
if (address) {
|
| 297 |
+
copyCryptoAddress(card, address);
|
| 298 |
+
}
|
| 299 |
+
});
|
| 300 |
+
});
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
+
// Copy crypto address with visual feedback
|
| 304 |
+
async function copyCryptoAddress(card, address) {
|
| 305 |
+
const copyIcon = card.querySelector('.copy-icon');
|
| 306 |
+
const checkIcon = card.querySelector('.check-icon');
|
| 307 |
+
const badge = card.querySelector('.copy-badge');
|
| 308 |
+
|
| 309 |
+
try {
|
| 310 |
+
if (navigator.clipboard && window.isSecureContext) {
|
| 311 |
+
await navigator.clipboard.writeText(address);
|
| 312 |
+
} else {
|
| 313 |
+
const ta = document.createElement('textarea');
|
| 314 |
+
ta.value = address;
|
| 315 |
+
ta.style.cssText = 'position:fixed;left:-9999px;top:0';
|
| 316 |
+
document.body.appendChild(ta);
|
| 317 |
+
ta.focus();
|
| 318 |
+
ta.select();
|
| 319 |
+
const success = document.execCommand('copy');
|
| 320 |
+
document.body.removeChild(ta);
|
| 321 |
+
if (!success) throw new Error('Copy command failed');
|
| 322 |
+
}
|
| 323 |
+
|
| 324 |
+
// Show success feedback
|
| 325 |
+
if (copyIcon) copyIcon.style.display = 'none';
|
| 326 |
+
if (checkIcon) {
|
| 327 |
+
checkIcon.style.display = 'block';
|
| 328 |
+
checkIcon.style.color = 'var(--color-success)';
|
| 329 |
+
}
|
| 330 |
+
if (badge) badge.style.display = 'inline-flex';
|
| 331 |
+
|
| 332 |
+
// Reset after delay
|
| 333 |
+
setTimeout(() => {
|
| 334 |
+
if (copyIcon) copyIcon.style.display = 'block';
|
| 335 |
+
if (checkIcon) checkIcon.style.display = 'none';
|
| 336 |
+
if (badge) badge.style.display = 'none';
|
| 337 |
+
}, 3000);
|
| 338 |
+
|
| 339 |
+
} catch (err) {
|
| 340 |
+
console.error('Failed to copy address:', err);
|
| 341 |
+
}
|
| 342 |
}
|
templates/index.html
CHANGED
|
@@ -79,6 +79,12 @@
|
|
| 79 |
<footer class="footer">
|
| 80 |
<div class="footer-inner">
|
| 81 |
<p class="footer-author">Created by <strong>adsurkasur</strong></p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
<div class="social-links">
|
| 83 |
<a href="https://github.com/adsurkasur/" target="_blank" rel="noopener noreferrer" class="social-link" aria-label="GitHub">
|
| 84 |
<svg fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
|
@@ -94,6 +100,229 @@
|
|
| 94 |
</div>
|
| 95 |
</footer>
|
| 96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
|
| 98 |
</body>
|
| 99 |
</html>
|
|
|
|
| 79 |
<footer class="footer">
|
| 80 |
<div class="footer-inner">
|
| 81 |
<p class="footer-author">Created by <strong>adsurkasur</strong></p>
|
| 82 |
+
<button type="button" class="btn-donate" id="donate-btn">
|
| 83 |
+
<svg fill="currentColor" viewBox="0 0 24 24">
|
| 84 |
+
<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/>
|
| 85 |
+
</svg>
|
| 86 |
+
Support Me
|
| 87 |
+
</button>
|
| 88 |
<div class="social-links">
|
| 89 |
<a href="https://github.com/adsurkasur/" target="_blank" rel="noopener noreferrer" class="social-link" aria-label="GitHub">
|
| 90 |
<svg fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
|
|
|
| 100 |
</div>
|
| 101 |
</footer>
|
| 102 |
|
| 103 |
+
<!-- QRIS Modal -->
|
| 104 |
+
<div class="modal-overlay" id="qris-modal">
|
| 105 |
+
<div class="modal-container qris-modal-container">
|
| 106 |
+
<div class="modal-header">
|
| 107 |
+
<div class="modal-title">
|
| 108 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 109 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm12 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1zM5 20h2a1 1 0 001-1v-2a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1z"/>
|
| 110 |
+
</svg>
|
| 111 |
+
QRIS
|
| 112 |
+
</div>
|
| 113 |
+
<button type="button" class="modal-close" id="qris-modal-close">
|
| 114 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 115 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
| 116 |
+
</svg>
|
| 117 |
+
</button>
|
| 118 |
+
</div>
|
| 119 |
+
<div class="modal-body qris-modal-body">
|
| 120 |
+
<img src="https://purple-given-lark-169.mypinata.cloud/ipfs/bafkreihplwmmtmq6youvqcfpiks4mffrdzc54h5ymqhfiq63bzzjfdiugq" alt="QRIS Payment" class="qris-image">
|
| 121 |
+
<a href="https://purple-given-lark-169.mypinata.cloud/ipfs/bafkreihplwmmtmq6youvqcfpiks4mffrdzc54h5ymqhfiq63bzzjfdiugq" download="qris-ade.jpg" class="btn-qris-download">
|
| 122 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 123 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"/>
|
| 124 |
+
</svg>
|
| 125 |
+
Download QRIS
|
| 126 |
+
</a>
|
| 127 |
+
</div>
|
| 128 |
+
</div>
|
| 129 |
+
</div>
|
| 130 |
+
|
| 131 |
+
<!-- Donation Modal -->
|
| 132 |
+
<div class="modal-overlay" id="donation-modal">
|
| 133 |
+
<div class="modal-container">
|
| 134 |
+
<div class="modal-header">
|
| 135 |
+
<div class="modal-title">
|
| 136 |
+
<svg fill="currentColor" viewBox="0 0 24 24">
|
| 137 |
+
<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/>
|
| 138 |
+
</svg>
|
| 139 |
+
Support Me
|
| 140 |
+
</div>
|
| 141 |
+
<button type="button" class="modal-close" id="modal-close">
|
| 142 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 143 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
| 144 |
+
</svg>
|
| 145 |
+
</button>
|
| 146 |
+
</div>
|
| 147 |
+
<div class="modal-body">
|
| 148 |
+
<p class="modal-description">
|
| 149 |
+
If you enjoy this app, consider supporting its development. Every contribution helps keep it free and improving!
|
| 150 |
+
</p>
|
| 151 |
+
|
| 152 |
+
<!-- Payment Platforms -->
|
| 153 |
+
<div class="donation-section">
|
| 154 |
+
<h3 class="donation-section-title">
|
| 155 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 156 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
| 157 |
+
</svg>
|
| 158 |
+
Payment Platforms
|
| 159 |
+
</h3>
|
| 160 |
+
<a href="https://trakteer.id/adsurkasur" target="_blank" rel="noopener noreferrer" class="donation-card">
|
| 161 |
+
<div class="donation-card-content">
|
| 162 |
+
<div class="donation-icon trakteer">
|
| 163 |
+
<svg fill="currentColor" viewBox="0 0 24 24">
|
| 164 |
+
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1.41 16.09V20h-2.67v-1.93c-1.71-.36-3.16-1.46-3.27-3.4h1.96c.1 1.05.82 1.87 2.65 1.87 1.96 0 2.4-.98 2.4-1.59 0-.83-.44-1.61-2.67-2.14-2.48-.6-4.18-1.62-4.18-3.67 0-1.72 1.39-2.84 3.11-3.21V4h2.67v1.95c1.86.45 2.79 1.86 2.85 3.39H14.3c-.05-1.11-.64-1.87-2.22-1.87-1.5 0-2.4.68-2.4 1.64 0 .84.65 1.39 2.67 1.91s4.18 1.39 4.18 3.91c-.01 1.83-1.38 2.83-3.12 3.16z"/>
|
| 165 |
+
</svg>
|
| 166 |
+
</div>
|
| 167 |
+
<div class="donation-info">
|
| 168 |
+
<div class="donation-name">Trakteer</div>
|
| 169 |
+
<div class="donation-label">trakteer.id/adsurkasur</div>
|
| 170 |
+
</div>
|
| 171 |
+
</div>
|
| 172 |
+
<div class="donation-action">
|
| 173 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 174 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
| 175 |
+
</svg>
|
| 176 |
+
</div>
|
| 177 |
+
</a>
|
| 178 |
+
<a href="https://ko-fi.com/adsurkasur" target="_blank" rel="noopener noreferrer" class="donation-card">
|
| 179 |
+
<div class="donation-card-content">
|
| 180 |
+
<div class="donation-icon kofi">
|
| 181 |
+
<svg fill="currentColor" viewBox="0 0 24 24">
|
| 182 |
+
<path d="M23.881 8.948c-.773-4.085-4.859-4.593-4.859-4.593H.723c-.604 0-.679.798-.679.798s-.082 7.324-.022 11.822c.164 2.424 2.586 2.672 2.586 2.672s8.267-.023 11.966-.049c2.438-.426 2.683-2.566 2.658-3.734 4.352.24 7.422-2.831 6.649-6.916zm-11.062 3.511c-1.246 1.453-4.011 3.976-4.011 3.976s-.121.119-.31.023c-.076-.057-.108-.09-.108-.09-.443-.441-3.368-3.049-4.034-3.954-.709-.965-1.041-2.7-.091-3.71.951-1.01 3.005-1.086 4.363.407 0 0 1.565-1.782 3.468-.963 1.904.82 1.832 3.011.723 4.311zm6.173.478c-.928.116-1.682.028-1.682.028V7.284h1.77s1.971.551 1.971 2.638c0 1.913-.985 2.667-2.059 3.015z"/>
|
| 183 |
+
</svg>
|
| 184 |
+
</div>
|
| 185 |
+
<div class="donation-info">
|
| 186 |
+
<div class="donation-name">Ko-fi</div>
|
| 187 |
+
<div class="donation-label">ko-fi.com/adsurkasur</div>
|
| 188 |
+
</div>
|
| 189 |
+
</div>
|
| 190 |
+
<div class="donation-action">
|
| 191 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 192 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
| 193 |
+
</svg>
|
| 194 |
+
</div>
|
| 195 |
+
</a>
|
| 196 |
+
<div class="donation-card" id="qris-card">
|
| 197 |
+
<div class="donation-card-content">
|
| 198 |
+
<div class="donation-icon qris">
|
| 199 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 200 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm12 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1zM5 20h2a1 1 0 001-1v-2a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1z"/>
|
| 201 |
+
</svg>
|
| 202 |
+
</div>
|
| 203 |
+
<div class="donation-info">
|
| 204 |
+
<div class="donation-name">QRIS</div>
|
| 205 |
+
<div class="donation-label">Scan to pay with any Indonesian e-wallet</div>
|
| 206 |
+
</div>
|
| 207 |
+
</div>
|
| 208 |
+
<div class="donation-action">
|
| 209 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 210 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
| 211 |
+
</svg>
|
| 212 |
+
</div>
|
| 213 |
+
</div>
|
| 214 |
+
</div>
|
| 215 |
+
|
| 216 |
+
<!-- Cryptocurrency -->
|
| 217 |
+
<div class="donation-section">
|
| 218 |
+
<h3 class="donation-section-title">
|
| 219 |
+
<svg fill="currentColor" viewBox="0 0 24 24">
|
| 220 |
+
<path d="M13.425 6.432c1.983.19 3.538.778 3.71 2.528.117 1.276-.438 2.035-1.355 2.463 1.481.359 2.382 1.202 2.196 3.072-.227 2.343-2.035 2.952-4.62 3.08l.004 2.42-1.522.002-.004-2.42c-.166-.002-.34 0-.519.003-.238.003-.484.006-.731-.001l.004 2.42-1.52.001-.004-2.42-3.044-.058.256-1.768s1.15.024 1.129.012c.423-.002.549-.293.58-.485l-.008-3.878.012-2.76c-.046-.288-.248-.634-.87-.644.033-.03-1.115.001-1.115.001L6 6.38l3.12-.005-.004-2.37 1.571-.002.004 2.37c.304-.008.603-.005.906-.003l.3.002-.005-2.37L13.422 4l.003 2.432zm-2.92 4.46l.076.002c.926.04 3.67.155 3.673-1.457-.004-1.532-2.339-1.482-3.423-1.46-.129.003-.24.006-.327.005v2.91zm.129 4.75l-.134-.005v-2.91c.097.002.218 0 .359-.002 1.282-.015 4.145-.05 4.132 1.494.014 1.597-3.218 1.468-4.357 1.423z"/>
|
| 221 |
+
</svg>
|
| 222 |
+
Cryptocurrency
|
| 223 |
+
</h3>
|
| 224 |
+
<div class="donation-card" data-crypto="bitcoin" data-address="bc1q7d4t6ne3a44x2sujd5ektlngc9j0jfzhyn38z5">
|
| 225 |
+
<div class="donation-card-content">
|
| 226 |
+
<div class="donation-icon bitcoin">
|
| 227 |
+
<svg viewBox="0 0 24 24" fill="currentColor">
|
| 228 |
+
<path d="M23.638 14.904c-1.602 6.43-8.113 10.34-14.542 8.736C2.67 22.05-1.244 15.525.362 9.105 1.962 2.67 8.475-1.243 14.9.358c6.43 1.605 10.342 8.115 8.738 14.546z"/>
|
| 229 |
+
<path fill="#fff" d="M17.27 10.25c.24-1.594-.976-2.452-2.638-3.023l.54-2.163-1.317-.328-.525 2.106c-.346-.087-.702-.168-1.056-.249l.53-2.12-1.317-.328-.54 2.163c-.286-.065-.567-.13-.84-.198l.001-.006-1.816-.454-.35 1.407s.976.224.955.237c.533.133.63.486.614.766l-.615 2.465c.037.01.084.024.137.046l-.14-.034-.862 3.452c-.065.162-.23.405-.603.313.013.02-.956-.239-.956-.239l-.652 1.509 1.714.427c.319.08.631.163.94.242l-.546 2.19 1.316.328.54-2.165c.36.098.71.188 1.05.273l-.538 2.156 1.317.328.545-2.186c2.244.425 3.932.253 4.64-1.776.571-1.634-.028-2.576-1.208-3.192.86-.198 1.506-.764 1.678-1.932zm-3.005 4.213c-.406 1.63-3.15.749-4.04.528l.72-2.893c.89.222 3.746.662 3.32 2.365zm.405-4.237c-.37 1.48-2.654.728-3.395.544l.654-2.622c.74.184 3.128.528 2.741 2.078z"/>
|
| 230 |
+
</svg>
|
| 231 |
+
</div>
|
| 232 |
+
<div class="donation-info">
|
| 233 |
+
<div class="donation-name">Bitcoin<span class="copy-badge" style="display:none;">Copied!</span></div>
|
| 234 |
+
<div class="donation-address">bc1q7d4t6ne3a44x2sujd5ektlngc9j0jfzhyn38z5</div>
|
| 235 |
+
</div>
|
| 236 |
+
</div>
|
| 237 |
+
<div class="donation-action">
|
| 238 |
+
<svg class="copy-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 239 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
| 240 |
+
</svg>
|
| 241 |
+
<svg class="check-icon" style="display:none;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 242 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
| 243 |
+
</svg>
|
| 244 |
+
</div>
|
| 245 |
+
</div>
|
| 246 |
+
<div class="donation-card" data-crypto="evm" data-address="0xc53F031fe8cE7970D6Ff00fE65ef80617a893B44">
|
| 247 |
+
<div class="donation-card-content">
|
| 248 |
+
<div class="donation-icon ethereum">
|
| 249 |
+
<svg viewBox="0 0 24 24" fill="currentColor">
|
| 250 |
+
<path d="M11.944 17.97L4.58 13.62 11.943 24l7.37-10.38-7.372 4.35h.003zM12.056 0L4.69 12.223l7.365 4.354 7.365-4.35L12.056 0z"/>
|
| 251 |
+
</svg>
|
| 252 |
+
</div>
|
| 253 |
+
<div class="donation-info">
|
| 254 |
+
<div class="donation-name">EVM (ETH/BNB/etc)<span class="copy-badge" style="display:none;">Copied!</span></div>
|
| 255 |
+
<div class="donation-address">0xc53F031fe8cE7970D6Ff00fE65ef80617a893B44</div>
|
| 256 |
+
</div>
|
| 257 |
+
</div>
|
| 258 |
+
<div class="donation-action">
|
| 259 |
+
<svg class="copy-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 260 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
| 261 |
+
</svg>
|
| 262 |
+
<svg class="check-icon" style="display:none;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 263 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
| 264 |
+
</svg>
|
| 265 |
+
</div>
|
| 266 |
+
</div>
|
| 267 |
+
<div class="donation-card" data-crypto="solana" data-address="3ymZGds5iphv4UNdSzv8DWaHeKGsCTe89sZwZMms2u9z">
|
| 268 |
+
<div class="donation-card-content">
|
| 269 |
+
<div class="donation-icon solana">
|
| 270 |
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 397.7 311.7" width="24" height="24">
|
| 271 |
+
<defs>
|
| 272 |
+
<linearGradient id="solana-grad" x1="360.8791" y1="351.4553" x2="141.213" y2="-69.2936" gradientTransform="matrix(1 0 0 -1 0 314)">
|
| 273 |
+
<stop offset="0" stopColor="#00FFA3"/>
|
| 274 |
+
<stop offset="1" stopColor="#DC1FFF"/>
|
| 275 |
+
</linearGradient>
|
| 276 |
+
</defs>
|
| 277 |
+
<path fill="url(#solana-grad)" d="M64.6,237.9c2.4-2.4,5.7-3.8,9.2-3.8h317.4c5.8,0,8.7,7,4.6,11.1l-62.7,62.7c-2.4,2.4-5.7,3.8-9.2,3.8H6.5c-5.8,0-8.7-7-4.6-11.1L64.6,237.9z"/>
|
| 278 |
+
<path fill="url(#solana-grad)" d="M64.6,3.8C67.1,1.4,70.4,0,73.8,0h317.4c5.8,0,8.7,7,4.6,11.1l-62.7,62.7c-2.4,2.4-5.7,3.8-9.2,3.8H6.5c-5.8,0-8.7-7-4.6-11.1L64.6,3.8z"/>
|
| 279 |
+
<path fill="url(#solana-grad)" d="M333.1,120.1c-2.4-2.4-5.7-3.8-9.2-3.8H6.5c-5.8,0-8.7,7-4.6,11.1l62.7,62.7c2.4,2.4,5.7,3.8,9.2,3.8h317.4c5.8,0,8.7-7,4.6-11.1L333.1,120.1z"/>
|
| 280 |
+
</svg>
|
| 281 |
+
</div>
|
| 282 |
+
<div class="donation-info">
|
| 283 |
+
<div class="donation-name">Solana<span class="copy-badge" style="display:none;">Copied!</span></div>
|
| 284 |
+
<div class="donation-address">3ymZGds5iphv4UNdSzv8DWaHeKGsCTe89sZwZMms2u9z</div>
|
| 285 |
+
</div>
|
| 286 |
+
</div>
|
| 287 |
+
<div class="donation-action">
|
| 288 |
+
<svg class="copy-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 289 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
| 290 |
+
</svg>
|
| 291 |
+
<svg class="check-icon" style="display:none;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 292 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
| 293 |
+
</svg>
|
| 294 |
+
</div>
|
| 295 |
+
</div>
|
| 296 |
+
<div class="donation-card" data-crypto="sui" data-address="0x232363195ab483e8721f995cc9dbfbf7573ac471a86e51c9a71538f82c86f5f6">
|
| 297 |
+
<div class="donation-card-content">
|
| 298 |
+
<div class="donation-icon sui">
|
| 299 |
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 383.5" width="24" height="24">
|
| 300 |
+
<path fill="#4DA2FF" fillRule="evenodd" clipRule="evenodd" d="M240.1,159.9c15.6,19.6,25,44.5,25,71.5s-9.6,52.6-25.7,72.4l-1.4,1.7l-0.4-2.2c-0.3-1.8-0.7-3.7-1.1-5.6c-8-35.3-34.2-65.6-77.4-90.2c-29.1-16.5-45.8-36.4-50.2-59c-2.8-14.6-0.7-29.3,3.3-41.9c4.1-12.6,10.1-23.1,15.2-29.4l16.8-20.5c2.9-3.6,8.5-3.6,11.4,0L240.1,159.9L240.1,159.9z M266.6,139.4L154.2,2c-2.1-2.6-6.2-2.6-8.3,0L33.4,139.4l-0.4,0.5C12.4,165.6,0,198.2,0,233.7c0,82.7,67.2,149.8,150,149.8c82.8,0,150-67.1,150-149.8c0-35.5-12.4-68.1-33.1-93.8L266.6,139.4L266.6,139.4z M60.3,159.5l10-12.3l0.3,2.3c0.2,1.8,0.5,3.6,0.9,5.4c6.5,34.1,29.8,62.6,68.6,84.6c33.8,19.2,53.4,41.3,59.1,65.6c2.4,10.1,2.8,20.1,1.8,28.8l-0.1,0.5l-0.5,0.2c-15.2,7.4-32.4,11.6-50.5,11.6c-63.5,0-115-51.4-115-114.8C34.9,204.2,44.4,179.1,60.3,159.5L60.3,159.5z"/>
|
| 301 |
+
</svg>
|
| 302 |
+
</div>
|
| 303 |
+
<div class="donation-info">
|
| 304 |
+
<div class="donation-name">Sui<span class="copy-badge" style="display:none;">Copied!</span></div>
|
| 305 |
+
<div class="donation-address">0x232363195ab483e8721f995cc9dbfbf7573ac471a86e51c9a71538f82c86f5f6</div>
|
| 306 |
+
</div>
|
| 307 |
+
</div>
|
| 308 |
+
<div class="donation-action">
|
| 309 |
+
<svg class="copy-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 310 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
| 311 |
+
</svg>
|
| 312 |
+
<svg class="check-icon" style="display:none;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 313 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
| 314 |
+
</svg>
|
| 315 |
+
</div>
|
| 316 |
+
</div>
|
| 317 |
+
</div>
|
| 318 |
+
|
| 319 |
+
<div class="modal-thank-you">
|
| 320 |
+
Thank you for considering supporting this project! 🙏
|
| 321 |
+
</div>
|
| 322 |
+
</div>
|
| 323 |
+
</div>
|
| 324 |
+
</div>
|
| 325 |
+
|
| 326 |
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
|
| 327 |
</body>
|
| 328 |
</html>
|