From 88aed9d16c6c9d04222d87589dc3adfc154a9405 Mon Sep 17 00:00:00 2001 From: Akshatverma79 Date: Mon, 25 May 2026 10:25:57 +0530 Subject: [PATCH] feat: additional changes before popping stash --- app/page.tsx | 118 +++++++++++---------------------------------------- 1 file changed, 24 insertions(+), 94 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 0cffb45..243ba18 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,4 +1,4 @@ -"use client" +"use client" const safeBase64Encode = (str: string) => btoa(unescape(encodeURIComponent(str))); @@ -17,7 +17,7 @@ import { CommandPalette, type Command } from "@/components/ui/command-palette" import { Code2, Play, Download, Upload, Layout, Maximize2, Minimize2, FileText, Palette, Zap, Sun, Moon, Search, Link as LinkIcon, - Undo2, Redo2, Timer, MoreHorizontal, X, + Undo2, Redo2, Timer, MoreHorizontal, X, LogIn, UserPlus, } from "lucide-react" import { toast } from "sonner" import * as prettier from 'prettier' @@ -154,6 +154,28 @@ const templates: Template[] = [ javascript: `let timer=null,seconds=0,running=false;function startStop(){const b=document.getElementById('startBtn');if(running){clearInterval(timer);b.textContent='Start';running=false}else{timer=setInterval(()=>{seconds++;update()},1000);b.textContent='Stop';running=true}}function reset(){clearInterval(timer);seconds=0;running=false;document.getElementById('startBtn').textContent='Start';update()}function update(){const h=Math.floor(seconds/3600),m=Math.floor((seconds%3600)/60),s=seconds%60;document.getElementById('display').textContent=String(h).padStart(2,'0')+':'+String(m).padStart(2,'0')+':'+String(s).padStart(2,'0')}`, }, }, + { + id: "login-form", + name: "Login Form", + description: "Animated glassmorphism login", + icon: , + content: { + html: `Login
`, + css: `body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#130a2e,#2d1b5a);font-family:'Segoe UI',system-ui,sans-serif;overflow:hidden;color:#fff}.blobs{position:absolute;inset:0;overflow:hidden;z-index:0}.blob{position:absolute;filter:blur(60px);border-radius:50%;opacity:0.6;animation:float 10s infinite ease-in-out alternate}.blob-1{width:300px;height:300px;background:#8b5cf6;top:-100px;left:-100px}.blob-2{width:400px;height:400px;background:#3b82f6;bottom:-150px;right:-100px;animation-delay:-5s}.blob-3{width:200px;height:200px;background:#ec4899;top:50%;left:50%;transform:translate(-50%,-50%);animation-delay:-2s}@keyframes float{0%{transform:translateY(0) scale(1)}100%{transform:translateY(30px) scale(1.1)}}.container{position:relative;z-index:1;width:100%;max-width:400px;padding:2rem}.login-form{background:rgba(255,255,255,0.05);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:1px solid rgba(255,255,255,0.1);padding:2.5rem;border-radius:24px;box-shadow:0 25px 50px -12px rgba(0,0,0,0.5);animation:slideUp 0.6s cubic-bezier(0.16,1,0.3,1)}@keyframes slideUp{from{opacity:0;transform:translateY(40px)}to{opacity:1;transform:translateY(0)}}.logo{font-size:3rem;text-align:center;color:#a855f7;animation:spin 10s linear infinite}h2{text-align:center;margin:1rem 0 0.5rem;font-size:1.75rem}.subtitle{text-align:center;color:#94a3b8;margin-bottom:2rem;font-size:0.9rem}.input-group{position:relative;margin-bottom:1.5rem}.input-group input{width:100%;padding:1rem;background:rgba(0,0,0,0.2);border:1px solid rgba(255,255,255,0.1);border-radius:12px;color:#fff;font-size:1rem;outline:none;transition:all 0.3s;box-sizing:border-box}.input-group input:focus,.input-group input:valid{border-color:#a855f7;background:rgba(0,0,0,0.3)}.input-group label{position:absolute;left:1rem;top:1rem;color:#94a3b8;transition:all 0.3s;pointer-events:none;font-size:1rem}.input-group input:focus~label,.input-group input:valid~label{top:-0.5rem;left:0.8rem;font-size:0.75rem;background:#2d1b5a;padding:0 0.4rem;color:#a855f7;border-radius:4px}.toggle-pwd{position:absolute;right:1rem;top:50%;transform:translateY(-50%);background:none;border:none;color:#94a3b8;cursor:pointer;font-size:1.2rem}.actions{display:flex;justify-content:space-between;align-items:center;margin-bottom:2rem;font-size:0.875rem}.remember{display:flex;align-items:center;gap:0.5rem;color:#94a3b8;cursor:pointer}.forgot{color:#a855f7;text-decoration:none;transition:color 0.3s}.forgot:hover{color:#d8b4fe}.submit-btn{width:100%;padding:1rem;background:linear-gradient(135deg,#a855f7,#3b82f6);border:none;border-radius:12px;color:#fff;font-size:1rem;font-weight:600;cursor:pointer;transition:transform 0.2s,box-shadow 0.2s;position:relative;overflow:hidden}.submit-btn:hover{transform:translateY(-2px);box-shadow:0 10px 20px rgba(168,85,247,0.3)}.social-login{margin-top:1.5rem;display:flex;gap:1rem}.social-btn{flex:1;padding:0.75rem;background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.1);border-radius:12px;color:#fff;cursor:pointer;transition:background 0.3s}.social-btn:hover{background:rgba(255,255,255,0.1)}`, + javascript: `const togglePwd=document.getElementById('togglePwd');const pwdInput=document.getElementById('password');togglePwd.addEventListener('click',()=>{const type=pwdInput.getAttribute('type')==='password'?'text':'password';pwdInput.setAttribute('type',type);togglePwd.textContent=type==='password'?'👁':'🙈'});document.getElementById('loginForm').addEventListener('submit',(e)=>{e.preventDefault();const btn=document.querySelector('.submit-btn');const originalText=btn.textContent;btn.innerHTML='';setTimeout(()=>{btn.textContent='Success!';btn.style.background='#22c55e';setTimeout(()=>{btn.textContent=originalText;btn.style.background='linear-gradient(135deg, #a855f7, #3b82f6)';e.target.reset()},2000)},1500)});`, + } + }, + { + id: "signup-form", + name: "Sign Up Form", + description: "Interactive animated registration", + icon: , + content: { + html: `Sign Up
`, + css: `body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#0f172a,#1e1b4b);font-family:'Segoe UI',system-ui,sans-serif;color:#fff}.container{width:100%;max-width:480px;padding:2rem;box-sizing:border-box}.signup-form{background:rgba(255,255,255,0.03);backdrop-filter:blur(16px);border:1px solid rgba(255,255,255,0.08);padding:2.5rem;border-radius:24px;box-shadow:0 30px 60px -15px rgba(0,0,0,0.6);animation:scaleIn 0.5s ease-out}@keyframes scaleIn{from{opacity:0;transform:scale(0.95)}to{opacity:1;transform:scale(1)}}.rocket{font-size:3.5rem;text-align:center;animation:bounce 2s infinite ease-in-out}@keyframes bounce{0%,100%{transform:translateY(0)}50%{transform:translateY(-15px)}}h2{text-align:center;margin:0.5rem 0;font-size:2rem;background:linear-gradient(to right,#2dd4bf,#a855f7);-webkit-background-clip:text;color:transparent}.subtitle{text-align:center;color:#94a3b8;margin-bottom:2rem}.name-grid{display:grid;grid-template-columns:1fr 1fr;gap:1rem}.input-group{position:relative;margin-bottom:1.5rem}.input-group input{width:100%;padding:1rem;background:rgba(0,0,0,0.25);border:1px solid rgba(255,255,255,0.1);border-radius:12px;color:#fff;font-size:1rem;outline:none;transition:all 0.3s;box-sizing:border-box}.input-group input:focus{border-color:#2dd4bf;box-shadow:0 0 0 4px rgba(45,212,191,0.1)}.input-group label{position:absolute;left:1rem;top:1rem;color:#94a3b8;transition:all 0.3s;pointer-events:none}.input-group input:focus~label,.input-group input:valid~label{top:-0.6rem;left:0.8rem;font-size:0.75rem;background:#1e1b4b;padding:0 0.4rem;color:#2dd4bf;border-radius:4px}.validation-icon{position:absolute;right:1rem;top:1rem}.strength-meter{height:4px;background:rgba(255,255,255,0.1);border-radius:2px;margin-top:0.5rem;overflow:hidden}.strength-bar{height:100%;width:0;transition:all 0.3s}.strength-text{font-size:0.75rem;margin-top:0.25rem;text-align:right}.terms{display:flex;align-items:center;gap:0.5rem;color:#94a3b8;font-size:0.875rem;margin-bottom:1.5rem}.terms a{color:#2dd4bf;text-decoration:none}.submit-btn{width:100%;padding:1rem;background:linear-gradient(135deg,#2dd4bf,#3b82f6);border:none;border-radius:12px;color:#fff;font-size:1.1rem;font-weight:600;cursor:pointer;transition:all 0.3s}.submit-btn:hover{transform:translateY(-2px);box-shadow:0 10px 20px rgba(45,212,191,0.3)}`, + javascript: `const pwd=document.getElementById('password');const bar=document.getElementById('strengthBar');const txt=document.getElementById('strengthText');const email=document.getElementById('email');const emailIcon=document.getElementById('emailIcon');pwd.addEventListener('input',(e)=>{const val=e.target.value;let strength=0;if(val.length>=8)strength++;if(val.match(/[A-Z]/))strength++;if(val.match(/[0-9]/))strength++;if(val.match(/[^A-Za-z0-9]/))strength++;let color,width,text;switch(strength){case 0:width='0';text='';break;case 1:width='25%';color='#ef4444';text='Weak';break;case 2:width='50%';color='#f97316';text='Fair';break;case 3:width='75%';color='#eab308';text='Good';break;case 4:width='100%';color='#22c55e';text='Strong 💪';break;}bar.style.width=width;bar.style.backgroundColor=color;txt.textContent=text;txt.style.color=color});email.addEventListener('blur',(e)=>{const val=e.target.value;if(val){const isValid=/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(val);emailIcon.textContent=isValid?'✅':'❌'}else{emailIcon.textContent=''}});document.getElementById('signupForm').addEventListener('submit',(e)=>{e.preventDefault();if(document.getElementById('password').value!==document.getElementById('confirm').value){alert('Passwords do not match!');return}const btn=document.querySelector('.submit-btn');btn.textContent='Creating...';setTimeout(()=>{btn.textContent='Account Created!';btn.style.background='#22c55e'},1500)});`, + } + }, ] type LayoutType = "split" | "preview" | "code" @@ -187,101 +209,9 @@ export default function CodeEditor() { const [isResizing, setIsResizing] = useState(false) - // use effect for handling full screen mode - useEffect(() => { - const handleFullscreenChange = () => { - setIsFullscreen(Boolean(document.fullscreenElement)); - }; - - document.addEventListener("fullscreenchange", handleFullscreenChange); - return () => { - document.removeEventListener("fullscreenchange", handleFullscreenChange); - }; - }, []); - - const handleFullscreenToggle = async () => { - try { - if (document.fullscreenElement) { - if (document.exitFullscreen) { - await document.exitFullscreen(); - } - return; - } - - if (isFullscreen) { - setIsFullscreen(false); - return; - } - - if (containerRef.current?.requestFullscreen) { - await containerRef.current.requestFullscreen(); - return; - } - - setIsFullscreen(true); - } catch (err) { - console.error("Error attempting to toggle fullscreen:", err); - setIsFullscreen((prev) => !prev); - } - }; - -const containerRef = useRef(null) -const previewRef = useRef(null) -const [isMobile, setIsMobile] = useState(false) - -useEffect(() => { - const updateIsMobile = () => { - setIsMobile(window.innerWidth < 768) - } - - updateIsMobile() - window.addEventListener("resize", updateIsMobile) - - return () => { - window.removeEventListener("resize", updateIsMobile) - } -}, []) - -const handleDragStart = () => { - isDragging.current = true; - setIsResizing(true); - document.body.style.userSelect = "none"; -}; - -const handleDragMove = useCallback((clientX: number, clientY: number) => { - if (!isDragging.current || !containerRef.current) return; - const rect = containerRef.current.getBoundingClientRect(); - - let newRatio; - if (isMobile) { - newRatio = ((clientY - rect.top) / rect.height) * 100; - } else { - newRatio = ((clientX - rect.left) / rect.width) * 100; - } - - const clampedRatio = Math.max(20, Math.min(80, newRatio)); - setSplitRatio(clampedRatio); -}, [isMobile]); - -const handleMouseMove = useCallback((e: globalThis.MouseEvent) => { - handleDragMove(e.clientX, e.clientY); -}, [handleDragMove]); - -const handleTouchMove = useCallback((e: globalThis.TouchEvent) => { - if (isDragging.current) { - handleDragMove(e.touches[0].clientX, e.touches[0].clientY); - } -}, [handleDragMove]); -const handleDragEnd = useCallback(() => { - isDragging.current = false; - setIsResizing(false); - document.body.style.userSelect = "auto"; - document.body.style.cursor = "default"; -}, []); - // Tracks which template is currently active const [isMobile, setIsMobile] = useState(false) const [consoleErrors, setConsoleErrors] = useState>([])