donation / index.html
hsnaruto's picture
Add 3 files
cd07086 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Support Our Cause | Donate Today</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.donation-option {
transition: all 0.3s ease;
}
.donation-option:hover {
transform: translateY(-3px);
}
.donation-option.selected {
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5);
}
.progress-bar {
height: 6px;
transition: width 0.5s ease;
}
.input-highlight {
transition: all 0.3s ease;
}
.input-highlight:focus-within {
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5);
}
.floating-label {
transition: all 0.2s ease;
transform-origin: left center;
}
.input-field:focus + .floating-label,
.input-field:not(:placeholder-shown) + .floating-label {
transform: translateY(-24px) scale(0.85);
color: #3b82f6;
}
.toast {
position: fixed;
top: 20px;
right: 20px;
padding: 15px 25px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
z-index: 1000;
transform: translateX(200%);
transition: transform 0.3s ease;
}
.toast.show {
transform: translateX(0);
}
.toast.success {
background-color: #48bb78;
color: white;
}
.toast.error {
background-color: #f56565;
color: white;
}
</style>
</head>
<body class="bg-gray-50 min-h-screen">
<!-- Toast Notification -->
<div id="toast" class="toast hidden"></div>
<div class="max-w-4xl mx-auto px-4 py-12">
<!-- Progress indicator -->
<div class="mb-8">
<div class="flex justify-between items-center mb-2">
<span class="text-sm font-medium text-gray-700">Donation Progress</span>
<span class="text-sm font-medium text-gray-700">65% to goal</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2.5">
<div class="progress-bar bg-blue-600 rounded-full" style="width: 65%"></div>
</div>
</div>
<!-- Header -->
<div class="text-center mb-10">
<h1 class="text-4xl font-bold text-gray-900 mb-3">Make a Difference Today</h1>
<p class="text-xl text-gray-600 max-w-2xl mx-auto">Your gift changes lives. Every donation helps us provide food, shelter, and education to those in need.</p>
</div>
<div class="flex flex-col lg:flex-row gap-8">
<!-- Donation Form -->
<div class="lg:w-2/3">
<div class="bg-white rounded-xl shadow-md overflow-hidden p-6">
<!-- Donation Amount -->
<div class="mb-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Select Donation Amount</h2>
<div class="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-4">
<button class="donation-option bg-white border border-gray-300 rounded-lg py-4 px-2 text-center font-medium hover:bg-gray-50" data-amount="10">
$10
</button>
<button class="donation-option bg-white border border-gray-300 rounded-lg py-4 px-2 text-center font-medium hover:bg-gray-50" data-amount="25">
$25
</button>
<button class="donation-option bg-blue-50 border-2 border-blue-500 rounded-lg py-4 px-2 text-center font-medium text-blue-700 selected" data-amount="50">
$50
</button>
<button class="donation-option bg-white border border-gray-300 rounded-lg py-4 px-2 text-center font-medium hover:bg-gray-50" data-amount="100">
$100
</button>
</div>
<div class="input-highlight relative border border-gray-300 rounded-lg p-1">
<input type="number" id="customAmount" placeholder=" " class="input-field w-full py-3 px-4 rounded-lg focus:outline-none">
<label for="customAmount" class="floating-label absolute left-4 top-3 text-gray-500 pointer-events-none">Custom Amount ($)</label>
<div class="absolute right-3 top-3 text-gray-500">USD</div>
</div>
</div>
<!-- Donation Frequency -->
<div class="mb-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Donation Frequency</h2>
<div class="grid grid-cols-2 gap-3">
<button id="oneTimeBtn" class="bg-blue-600 text-white py-3 px-4 rounded-lg font-medium">One-Time</button>
<button id="recurringBtn" class="bg-white border border-gray-300 text-gray-700 py-3 px-4 rounded-lg font-medium hover:bg-gray-50">Monthly</button>
</div>
</div>
<!-- Payment Information -->
<div class="mb-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Payment Information</h2>
<div class="space-y-4">
<div class="input-highlight relative border border-gray-300 rounded-lg p-1">
<input type="text" id="cardName" placeholder=" " class="input-field w-full py-3 px-4 rounded-lg focus:outline-none">
<label for="cardName" class="floating-label absolute left-4 top-3 text-gray-500 pointer-events-none">Name on Card</label>
</div>
<div class="input-highlight relative border border-gray-300 rounded-lg p-1">
<input type="text" id="cardNumber" placeholder=" " class="input-field w-full py-3 px-4 rounded-lg focus:outline-none" maxlength="19">
<label for="cardNumber" class="floating-label absolute left-4 top-3 text-gray-500 pointer-events-none">Card Number</label>
<div class="absolute right-3 top-3 text-gray-500">
<i class="fab fa-cc-visa"></i>
<i class="fab fa-cc-mastercard ml-1"></i>
<i class="fab fa-cc-amex ml-1"></i>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<div class="input-highlight relative border border-gray-300 rounded-lg p-1">
<input type="text" id="cardExpiry" placeholder=" " class="input-field w-full py-3 px-4 rounded-lg focus:outline-none" maxlength="5">
<label for="cardExpiry" class="floating-label absolute left-4 top-3 text-gray-500 pointer-events-none">MM/YY</label>
</div>
<div class="input-highlight relative border border-gray-300 rounded-lg p-1">
<input type="text" id="cardCvv" placeholder=" " class="input-field w-full py-3 px-4 rounded-lg focus:outline-none" maxlength="4">
<label for="cardCvv" class="floating-label absolute left-4 top-3 text-gray-500 pointer-events-none">CVV</label>
</div>
</div>
</div>
</div>
<!-- Donor Information -->
<div class="mb-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Your Information</h2>
<div class="space-y-4">
<div class="input-highlight relative border border-gray-300 rounded-lg p-1">
<input type="text" id="fullName" placeholder=" " class="input-field w-full py-3 px-4 rounded-lg focus:outline-none">
<label for="fullName" class="floating-label absolute left-4 top-3 text-gray-500 pointer-events-none">Full Name</label>
</div>
<div class="input-highlight relative border border-gray-300 rounded-lg p-1">
<input type="email" id="email" placeholder=" " class="input-field w-full py-3 px-4 rounded-lg focus:outline-none">
<label for="email" class="floating-label absolute left-4 top-3 text-gray-500 pointer-events-none">Email Address</label>
</div>
</div>
</div>
<!-- Extras -->
<div class="mb-8">
<div class="flex items-start mb-4">
<div class="flex items-center h-5">
<input id="dedication" type="checkbox" class="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500">
</div>
<label for="dedication" class="ml-3 text-sm text-gray-700">Dedicate this donation (add a message)</label>
</div>
<div id="dedicationMessageContainer" class="hidden mt-2">
<textarea id="dedicationMessage" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Your dedication message..."></textarea>
</div>
<div class="flex items-start">
<div class="flex items-center h-5">
<input id="newsletter" type="checkbox" checked class="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500">
</div>
<label for="newsletter" class="ml-3 text-sm text-gray-700">Receive updates about our work (you can unsubscribe anytime)</label>
</div>
</div>
<!-- Security and Submit -->
<div class="border-t pt-6">
<div class="flex flex-col sm:flex-row justify-between items-center gap-4 mb-6">
<div class="flex items-center space-x-2">
<i class="fas fa-lock text-green-600"></i>
<span class="text-sm text-gray-600">Secure payment processing</span>
</div>
<div class="flex space-x-4">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/MasterCard_Logo.svg/2560px-MasterCard_Logo.svg.png" class="h-6" alt="Mastercard">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/5e/Visa_Inc._logo.svg/2560px-Visa_Inc._logo.svg.png" class="h-6" alt="Visa">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/39/PayPal_logo.svg/2560px-PayPal_logo.svg.png" class="h-6" alt="PayPal">
</div>
</div>
<button id="donateBtn" class="w-full bg-green-600 hover:bg-green-700 text-white font-bold py-4 px-6 rounded-lg text-lg transition duration-200 transform hover:scale-105">
Donate Now <i class="fas fa-heart ml-2"></i>
</button>
<p class="text-xs text-gray-500 mt-3 text-center">Your donation is tax-deductible as allowed by law. <a href="#" class="text-blue-600 hover:underline">Privacy Policy</a></p>
</div>
</div>
</div>
<!-- Sidebar -->
<div class="lg:w-1/3">
<div class="bg-white rounded-xl shadow-md overflow-hidden sticky top-6">
<div class="bg-blue-600 text-white p-4">
<h3 class="font-bold text-lg">Your Donation Summary</h3>
</div>
<div class="p-6">
<div class="flex justify-between items-center mb-4">
<span class="text-gray-600">Amount:</span>
<span id="summaryAmount" class="font-bold text-gray-900">$50.00</span>
</div>
<div class="flex justify-between items-center mb-4">
<span class="text-gray-600">Frequency:</span>
<span id="summaryFrequency" class="font-bold text-gray-900">One-Time</span>
</div>
<div class="border-t border-gray-200 my-4"></div>
<div class="flex justify-between items-center mb-2">
<span class="text-gray-600">Total:</span>
<span id="summaryTotal" class="font-bold text-xl text-gray-900">$50.00</span>
</div>
<p class="text-sm text-gray-500 mt-4">Thank you for your generosity! Your support makes a real difference.</p>
</div>
</div>
<!-- Impact Section -->
<div class="mt-6 bg-white rounded-xl shadow-md overflow-hidden">
<div class="bg-green-600 text-white p-4">
<h3 class="font-bold text-lg">Your Impact</h3>
</div>
<div class="p-6">
<div class="flex items-start mb-4">
<div class="bg-green-100 p-3 rounded-full mr-4">
<i class="fas fa-utensils text-green-600"></i>
</div>
<div>
<h4 class="font-medium text-gray-900">Provide meals</h4>
<p class="text-sm text-gray-600">$50 provides 25 meals for hungry families</p>
</div>
</div>
<div class="flex items-start mb-4">
<div class="bg-blue-100 p-3 rounded-full mr-4">
<i class="fas fa-book text-blue-600"></i>
</div>
<div>
<h4 class="font-medium text-gray-900">Support education</h4>
<p class="text-sm text-gray-600">$100 provides school supplies for 5 children</p>
</div>
</div>
<div class="flex items-start">
<div class="bg-purple-100 p-3 rounded-full mr-4">
<i class="fas fa-home text-purple-600"></i>
</div>
<div>
<h4 class="font-medium text-gray-900">Safe shelter</h4>
<p class="text-sm text-gray-600">$200 provides a week of safe housing</p>
</div>
</div>
</div>
</div>
<!-- Social Sharing -->
<div class="mt-6 bg-white rounded-xl shadow-md overflow-hidden">
<div class="p-4">
<h3 class="font-bold text-lg text-gray-900 mb-3">Spread the Word</h3>
<div class="flex justify-center space-x-4">
<button class="bg-blue-500 text-white p-3 rounded-full hover:bg-blue-600">
<i class="fab fa-facebook-f"></i>
</button>
<button class="bg-blue-400 text-white p-3 rounded-full hover:bg-blue-500">
<i class="fab fa-twitter"></i>
</button>
<button class="bg-pink-600 text-white p-3 rounded-full hover:bg-pink-700">
<i class="fab fa-instagram"></i>
</button>
<button class="bg-green-500 text-white p-3 rounded-full hover:bg-green-600">
<i class="fab fa-whatsapp"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Backend Simulation -->
<script>
// Database simulation
const database = {
donations: [],
donors: []
};
// Toast notification function
function showToast(message, type = 'success') {
const toast = document.getElementById('toast');
toast.textContent = message;
toast.className = `toast ${type} show`;
setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
document.addEventListener('DOMContentLoaded', function() {
// Default values
let donationAmount = 50;
let isRecurring = false;
// DOM Elements
const donationOptions = document.querySelectorAll('.donation-option');
const customAmountInput = document.getElementById('customAmount');
const oneTimeBtn = document.getElementById('oneTimeBtn');
const recurringBtn = document.getElementById('recurringBtn');
const donateBtn = document.getElementById('donateBtn');
const summaryAmount = document.getElementById('summaryAmount');
const summaryFrequency = document.getElementById('summaryFrequency');
const summaryTotal = document.getElementById('summaryTotal');
const dedicationCheckbox = document.getElementById('dedication');
const dedicationMessageContainer = document.getElementById('dedicationMessageContainer');
// Toggle dedication message field
dedicationCheckbox.addEventListener('change', function() {
if (this.checked) {
dedicationMessageContainer.classList.remove('hidden');
} else {
dedicationMessageContainer.classList.add('hidden');
}
});
// Format card number
const cardNumberInput = document.getElementById('cardNumber');
cardNumberInput.addEventListener('input', function(e) {
let value = e.target.value.replace(/\s+/g, '');
if (value.length > 0) {
value = value.match(new RegExp('.{1,4}', 'g')).join(' ');
}
e.target.value = value;
});
// Format expiry date
const cardExpiryInput = document.getElementById('cardExpiry');
cardExpiryInput.addEventListener('input', function(e) {
let value = e.target.value;
if (value.length === 2 && !value.includes('/')) {
e.target.value = value + '/';
}
});
// Select donation amount
donationOptions.forEach(option => {
option.addEventListener('click', function() {
// Remove selected class from all options
donationOptions.forEach(opt => {
opt.classList.remove('bg-blue-50', 'border-blue-500', 'text-blue-700', 'selected');
opt.classList.add('bg-white', 'border-gray-300');
});
// Add selected class to clicked option
this.classList.remove('bg-white', 'border-gray-300');
this.classList.add('bg-blue-50', 'border-blue-500', 'text-blue-700', 'selected');
// Update donation amount
donationAmount = parseFloat(this.dataset.amount);
updateSummary();
// Clear custom amount if any
customAmountInput.value = '';
});
});
// Handle custom amount input
customAmountInput.addEventListener('input', function() {
if (this.value) {
// Remove selected class from all preset options
donationOptions.forEach(opt => {
opt.classList.remove('bg-blue-50', 'border-blue-500', 'text-blue-700', 'selected');
opt.classList.add('bg-white', 'border-gray-300');
});
// Update donation amount
donationAmount = parseFloat(this.value) || 0;
updateSummary();
}
});
// Toggle donation frequency
oneTimeBtn.addEventListener('click', function() {
isRecurring = false;
oneTimeBtn.classList.remove('bg-white', 'border-gray-300', 'text-gray-700');
oneTimeBtn.classList.add('bg-blue-600', 'text-white');
recurringBtn.classList.remove('bg-blue-600', 'text-white');
recurringBtn.classList.add('bg-white', 'border-gray-300', 'text-gray-700');
updateSummary();
});
recurringBtn.addEventListener('click', function() {
isRecurring = true;
recurringBtn.classList.remove('bg-white', 'border-gray-300', 'text-gray-700');
recurringBtn.classList.add('bg-blue-600', 'text-white');
oneTimeBtn.classList.remove('bg-blue-600', 'text-white');
oneTimeBtn.classList.add('bg-white', 'border-gray-300', 'text-gray-700');
updateSummary();
});
// Update summary section
function updateSummary() {
summaryAmount.textContent = `$${donationAmount.toFixed(2)}`;
summaryFrequency.textContent = isRecurring ? 'Monthly' : 'One-Time';
summaryTotal.textContent = `$${donationAmount.toFixed(2)}`;
}
// Validate form fields
function validateForm() {
const fullName = document.getElementById('fullName').value.trim();
const email = document.getElementById('email').value.trim();
const cardName = document.getElementById('cardName').value.trim();
const cardNumber = document.getElementById('cardNumber').value.trim();
const cardExpiry = document.getElementById('cardExpiry').value.trim();
const cardCvv = document.getElementById('cardCvv').value.trim();
if (donationAmount <= 0) {
showToast('Please select or enter a donation amount', 'error');
return false;
}
if (!fullName) {
showToast('Please enter your full name', 'error');
return false;
}
if (!email || !/^\S+@\S+\.\S+$/.test(email)) {
showToast('Please enter a valid email address', 'error');
return false;
}
if (!cardName) {
showToast('Please enter the name on card', 'error');
return false;
}
if (!cardNumber || cardNumber.replace(/\s/g, '').length < 16) {
showToast('Please enter a valid card number', 'error');
return false;
}
if (!cardExpiry || !/^\d{2}\/\d{2}$/.test(cardExpiry)) {
showToast('Please enter a valid expiry date (MM/YY)', 'error');
return false;
}
if (!cardCvv || cardCvv.length < 3) {
showToast('Please enter a valid CVV', 'error');
return false;
}
return true;
}
// Handle donation submission
donateBtn.addEventListener('click', function() {
if (!validateForm()) return;
// Collect form data
const donationData = {
amount: donationAmount,
frequency: isRecurring ? 'monthly' : 'one-time',
donor: {
name: document.getElementById('fullName').value.trim(),
email: document.getElementById('email').value.trim()
},
payment: {
cardName: document.getElementById('cardName').value.trim(),
cardLast4: document.getElementById('cardNumber').value.trim().slice(-4),
cardExpiry: document.getElementById('cardExpiry').value.trim()
},
dedication: dedicationCheckbox.checked ? document.getElementById('dedicationMessage').value.trim() : null,
subscribeToNewsletter: document.getElementById('newsletter').checked,
date: new Date().toISOString()
};
// Simulate API call to backend
setTimeout(() => {
// Store donation in "database"
database.donations.push(donationData);
// Check if donor exists
const existingDonor = database.donors.find(d => d.email === donationData.donor.email);
if (!existingDonor) {
database.donors.push({
name: donationData.donor.name,
email: donationData.donor.email,
totalDonated: donationData.amount,
donationsCount: 1,
isSubscribed: donationData.subscribeToNewsletter,
firstDonationDate: new Date().toISOString()
});
} else {
existingDonor.totalDonated += donationData.amount;
existingDonor.donationsCount += 1;
existingDonor.isSubscribed = donationData.subscribeToNewsletter;
}
// Show success message
showToast(`Thank you for your donation of $${donationAmount.toFixed(2)}!`, 'success');
// Reset form
resetForm();
}, 1000);
});
// Reset form after submission
function resetForm() {
donationOptions.forEach(opt => {
opt.classList.remove('bg-blue-50', 'border-blue-500', 'text-blue-700', 'selected');
opt.classList.add('bg-white', 'border-gray-300');
});
document.querySelector('[data-amount="50"]').classList.add('bg-blue-50', 'border-blue-500', 'text-blue-700', 'selected');
customAmountInput.value = '';
document.getElementById('fullName').value = '';
document.getElementById('email').value = '';
document.getElementById('cardName').value = '';
document.getElementById('cardNumber').value = '';
document.getElementById('cardExpiry').value = '';
document.getElementById('cardCvv').value = '';
dedicationCheckbox.checked = false;
document.getElementById('dedicationMessage').value = '';
dedicationMessageContainer.classList.add('hidden');
document.getElementById('newsletter').checked = true;
donationAmount = 50;
isRecurring = false;
oneTimeBtn.classList.remove('bg-white', 'border-gray-300', 'text-gray-700');
oneTimeBtn.classList.add('bg-blue-600', 'text-white');
recurringBtn.classList.remove('bg-blue-600', 'text-white');
recurringBtn.classList.add('bg-white', 'border-gray-300', 'text-gray-700');
updateSummary();
}
});
</script>
<!-- Backend Server Simulation (Node.js/Express style) -->
<script>
// This is a simulation of what the backend would look like in a real application
// In a real app, this would be in a separate Node.js server file
/*
// Real backend would look something like this:
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
app.use(cors());
app.use(bodyParser.json());
// Connect to MongoDB
mongoose.connect('mongodb://localhost:27017/donations', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// Define Donation schema
const donationSchema = new mongoose.Schema({
amount: Number,
frequency: String,
donor: {
name: String,
email: String
},
payment: {
cardName: String,
cardLast4: String,
cardExpiry: String
},
dedication: String,
subscribeToNewsletter: Boolean,
date: Date
});
const Donation = mongoose.model('Donation', donationSchema);
// Define Donor schema
const donorSchema = new mongoose.Schema({
name: String,
email: { type: String, unique: true },
totalDonated: Number,
donationsCount: Number,
isSubscribed: Boolean,
firstDonationDate: Date,
lastDonationDate: Date
});
const Donor = mongoose.model('Donor', donorSchema);
// Process donation endpoint
app.post('/api/donations', async (req, res) => {
try {
const donation = new Donation(req.body);
await donation.save();
// Update or create donor
let donor = await Donor.findOne({ email: req.body.donor.email });
if (!donor) {
donor = new Donor({
name: req.body.donor.name,
email: req.body.donor.email,
totalDonated: req.body.amount,
donationsCount: 1,
isSubscribed: req.body.subscribeToNewsletter,
firstDonationDate: new Date(),
lastDonationDate: new Date()
});
} else {
donor.totalDonated += req.body.amount;
donor.donationsCount += 1;
donor.isSubscribed = req.body.subscribeToNewsletter;
donor.lastDonationDate = new Date();
}
await donor.save();
res.status(201).json({ message: 'Donation processed successfully' });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Get donations endpoint
app.get('/api/donations', async (req, res) => {
try {
const donations = await Donation.find().sort({ date: -1 });
res.json(donations);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Get donors endpoint
app.get('/api/donors', async (req, res) => {
try {
const donors = await Donor.find().sort({ totalDonated: -1 });
res.json(donors);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Start server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
*/
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=hsnaruto/donation" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>