parv.ashwani hai 5 meses
pai
achega
abb937e802
Modificáronse 3 ficheiros con 423 adicións e 0 borrados
  1. 1 0
      .gitignore
  2. 154 0
      index.html
  3. 268 0
      indexdev.html

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+.vercel

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 154 - 0
index.html


+ 268 - 0
indexdev.html

@@ -0,0 +1,268 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>ZPAY - Instant UPI Links</title>
+    
+    <!-- Tailwind CSS -->
+    <script src="https://cdn.tailwindcss.com"></script>
+    
+    <!-- QR Code Library -->
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
+
+    <style>
+        @import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;600;700&display=swap');
+        body { font-family: 'Plus Jakarta Sans', sans-serif; }
+        .fade-in { animation: fadeIn 0.5s ease-in; }
+        @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
+        
+        /* Custom Scrollbar for cleaner look */
+        ::-webkit-scrollbar { width: 8px; }
+        ::-webkit-scrollbar-track { background: #f1f5f9; }
+        ::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; }
+        ::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
+    </style>
+</head>
+<body class="bg-slate-50 text-slate-800 min-h-screen flex flex-col">
+
+    <!-- Navbar -->
+    <nav class="bg-white border-b border-slate-200 sticky top-0 z-50 backdrop-blur-md bg-white/90">
+        <div class="max-w-5xl mx-auto px-4 py-4 flex items-center justify-between">
+            <div class="flex items-center space-x-2 cursor-pointer" onclick="window.location.href=window.location.pathname">
+                <div class="bg-indigo-600 text-white p-1 rounded-lg">
+                    <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path></svg>
+                </div>
+                <span class="text-2xl font-bold tracking-tight text-slate-900">ZPAY</span>
+            </div>
+            <button onclick="resetApp()" class="text-sm font-medium text-slate-500 hover:text-indigo-600 transition">
+                New QR
+            </button>
+        </div>
+    </nav>
+
+    <!-- Main Content -->
+    <main class="max-w-5xl mx-auto px-4 py-10 flex-grow">
+        
+        <!-- Header -->
+        <div class="text-center mb-10" id="mainHeader">
+            <h1 class="text-3xl md:text-5xl font-bold mb-4 text-slate-900">Payments made simple.</h1>
+            <p class="text-slate-500 text-lg">Generate shareable smart links for your UPI ID.</p>
+        </div>
+
+        <div class="grid md:grid-cols-2 gap-8 items-start">
+            
+            <!-- Left Column: Input Form -->
+            <div class="bg-white p-6 md:p-8 rounded-3xl shadow-xl shadow-slate-200/50 border border-slate-100 relative overflow-hidden">
+                <div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500"></div>
+                
+                <h2 class="text-xl font-bold mb-6 text-slate-800">Payment Details</h2>
+
+                <div class="space-y-5">
+                    <!-- Payee Name -->
+                    <div>
+                        <label class="block text-xs font-semibold text-slate-500 uppercase tracking-wider mb-1">Payee Name <span class="text-indigo-500">*</span></label>
+                        <input type="text" id="upiName" placeholder="e.g. Rahul Sharma" 
+                            class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition font-medium">
+                    </div>
+
+                    <!-- UPI ID -->
+                    <div>
+                        <label class="block text-xs font-semibold text-slate-500 uppercase tracking-wider mb-1">UPI ID / VPA <span class="text-indigo-500">*</span></label>
+                        <input type="text" id="upiId" placeholder="e.g. rahul@oksbi" 
+                            class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition font-medium">
+                        <p class="text-xs text-red-500 mt-1 hidden font-medium" id="upiError">Invalid UPI ID format.</p>
+                    </div>
+
+                    <!-- Amount & Note Group -->
+                    <div class="grid grid-cols-2 gap-4">
+                        <div>
+                            <label class="block text-xs font-semibold text-slate-500 uppercase tracking-wider mb-1">Amount (₹)</label>
+                            <input type="number" id="upiAmount" placeholder="0.00" 
+                                class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition font-medium">
+                        </div>
+                        <div>
+                            <label class="block text-xs font-semibold text-slate-500 uppercase tracking-wider mb-1">Note</label>
+                            <input type="text" id="upiNote" placeholder="Bill / Gift" 
+                                class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition font-medium">
+                        </div>
+                    </div>
+
+                    <button onclick="generateZPayLink()" 
+                        class="w-full bg-slate-900 hover:bg-indigo-600 text-white font-bold py-4 rounded-xl transition-all duration-300 shadow-lg hover:shadow-indigo-500/30 transform hover:-translate-y-1">
+                        Generate ZPAY Link
+                    </button>
+                </div>
+            </div>
+
+            <!-- Right Column: Results -->
+            <div class="bg-white p-6 md:p-8 rounded-3xl shadow-xl shadow-slate-200/50 border border-slate-100 relative overflow-hidden min-h-[400px] flex flex-col justify-center">
+                
+                <!-- Placeholder State -->
+                <div id="placeholder-state" class="flex flex-col items-center justify-center text-center">
+                    <div class="w-20 h-20 bg-slate-50 rounded-full flex items-center justify-center mb-4">
+                        <svg class="w-10 h-10 text-slate-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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"></path></svg>
+                    </div>
+                    <h3 class="text-lg font-semibold text-slate-800">No Link Generated Yet</h3>
+                    <p class="text-slate-500 text-sm mt-1 max-w-xs">Enter your payment details on the left to create a unique QR and smart link.</p>
+                </div>
+
+                <!-- Result State -->
+                <div id="result-state" class="hidden fade-in w-full">
+                    <div class="text-center mb-6">
+                        <span class="inline-block px-3 py-1 bg-green-100 text-green-700 text-xs font-bold uppercase rounded-full tracking-wide">Ready to Pay</span>
+                        <h2 class="text-2xl font-bold mt-2 text-slate-900" id="displayPayee">Payee Name</h2>
+                        <p class="text-2xl font-light text-slate-500" id="displayAmount">₹0</p>
+                    </div>
+
+                    <!-- QR Container -->
+                    <div class="flex justify-center mb-8">
+                        <div class="p-4 bg-white rounded-2xl border-2 border-dashed border-indigo-200 shadow-sm relative group">
+                            <div id="qrcode"></div>
+                            <!-- Logo Overlay on QR (Optional visual flair) -->
+                            <div class="absolute inset-0 flex items-center justify-center pointer-events-none opacity-10">
+                                <svg class="w-12 h-12" fill="currentColor" viewBox="0 0 24 24"><path d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
+                            </div>
+                        </div>
+                    </div>
+
+                    <!-- Shareable Link -->
+                    <div class="bg-slate-50 rounded-xl p-4 border border-slate-200">
+                        <label class="block text-xs font-semibold text-slate-500 uppercase tracking-wider mb-2">Unique Smart Link</label>
+                        <div class="flex items-center gap-2">
+                            <input type="text" id="shareableLink" readonly 
+                                class="w-full bg-white border border-slate-200 text-slate-600 text-sm rounded-lg px-3 py-2 focus:outline-none select-all">
+                            <button onclick="copyLink()" 
+                                class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg text-sm font-medium transition whitespace-nowrap">
+                                Copy
+                            </button>
+                        </div>
+                        <p id="copyFeedback" class="text-center text-green-600 text-xs font-bold mt-2 opacity-0 transition-opacity">Copied to clipboard!</p>
+                    </div>
+                </div>
+
+            </div>
+        </div>
+        
+        <div class="mt-12 text-center">
+            <p class="text-slate-400 text-sm">Build by Parv Ashwani. ZPAY runs 100% in your browser. No data is stored.</p>
+        </div>
+
+    </main>
+
+    <!-- Application Logic -->
+    <script>
+        // Check for Shared URL Parameters on Load
+        window.addEventListener('load', () => {
+            if(window.location.hash) {
+                try {
+                    // Extract data from hash (remove the #)
+                    const hash = window.location.hash.substring(1);
+                    // Decode Base64 string to JSON
+                    const data = JSON.parse(decodeURIComponent(escape(atob(hash))));
+                    
+                    // Fill inputs
+                    document.getElementById('upiName').value = data.pn || '';
+                    document.getElementById('upiId').value = data.pa || '';
+                    document.getElementById('upiAmount').value = data.am || '';
+                    document.getElementById('upiNote').value = data.tn || '';
+
+                    // Auto Generate view
+                    generateZPayLink(true); // true = viewing mode
+                } catch (e) {
+                    console.error("Invalid Link Data", e);
+                    // Clear hash if invalid
+                    history.pushState("", document.title, window.location.pathname);
+                }
+            }
+        });
+
+        function generateZPayLink(isViewMode = false) {
+            // 1. Get Values
+            const name = document.getElementById('upiName').value.trim();
+            const vpa = document.getElementById('upiId').value.trim();
+            const amount = document.getElementById('upiAmount').value.trim();
+            const note = document.getElementById('upiNote').value.trim();
+            const errorMsg = document.getElementById('upiError');
+
+            // 2. Validation
+            if (!vpa || !vpa.includes('@')) {
+                errorMsg.classList.remove('hidden');
+                // Shake animation for input
+                document.getElementById('upiId').classList.add('ring-2', 'ring-red-500');
+                setTimeout(() => document.getElementById('upiId').classList.remove('ring-2', 'ring-red-500'), 500);
+                return;
+            }
+            if(!name) {
+                alert("Please enter a Payee Name");
+                return;
+            }
+            errorMsg.classList.add('hidden');
+
+            // 3. Construct Raw UPI String (for QR)
+            // upi://pay?pa=address&pn=name&am=amount&tn=note&cu=INR
+            let upiString = `upi://pay?pa=${vpa}&pn=${encodeURIComponent(name)}&cu=INR`;
+            if (amount) upiString += `&am=${amount}`;
+            if (note) upiString += `&tn=${encodeURIComponent(note)}`;
+
+            // 4. Construct Unique Smart Link (Base64 Encoded Hash)
+            // We encode the data object into a base64 string to create a shareable URL
+            const dataObj = { pa: vpa, pn: name, am: amount, tn: note };
+            // utf-8 safe base64 encoding
+            const hashPayload = btoa(unescape(encodeURIComponent(JSON.stringify(dataObj))));
+            const uniqueUrl = `${window.location.origin}${window.location.pathname}#${hashPayload}`;
+
+            // 5. Update UI
+            document.getElementById('displayPayee').innerText = name;
+            document.getElementById('displayAmount').innerText = amount ? `₹${amount}` : 'Enter Amount';
+            document.getElementById('shareableLink').value = uniqueUrl;
+
+            // Toggle Views
+            document.getElementById('placeholder-state').classList.add('hidden');
+            document.getElementById('result-state').classList.remove('hidden');
+
+            // 6. Generate QR Code
+            const qrContainer = document.getElementById("qrcode");
+            qrContainer.innerHTML = ""; // Clear old
+            
+            new QRCode(qrContainer, {
+                text: upiString,
+                width: 180,
+                height: 180,
+                colorDark : "#1e293b", // Slate-800
+                colorLight : "#ffffff",
+                correctLevel : QRCode.CorrectLevel.M
+            });
+
+            // If user clicked Generate, scroll to result on mobile
+            if(!isViewMode && window.innerWidth < 768) {
+                document.getElementById('result-state').scrollIntoView({behavior: 'smooth'});
+            }
+        }
+
+        function copyLink() {
+            const copyText = document.getElementById("shareableLink");
+            copyText.select();
+            copyText.setSelectionRange(0, 99999);
+            navigator.clipboard.writeText(copyText.value).then(() => {
+                const feedback = document.getElementById('copyFeedback');
+                feedback.style.opacity = '1';
+                setTimeout(() => feedback.style.opacity = '0', 2000);
+            });
+        }
+
+        function resetApp() {
+            // Clear inputs and URL hash
+            document.getElementById('upiName').value = '';
+            document.getElementById('upiId').value = '';
+            document.getElementById('upiAmount').value = '';
+            document.getElementById('upiNote').value = '';
+            history.pushState("", document.title, window.location.pathname);
+            
+            // Reset View
+            document.getElementById('result-state').classList.add('hidden');
+            document.getElementById('placeholder-state').classList.remove('hidden');
+        }
+    </script>
+</body>
+</html>

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio