diff --git a/.eslintrc.json b/.eslintrc.json index c06ee99..3722418 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,5 +1,3 @@ -// { -// "extends": ["next/core-web-vitals", "next/typescript"] -// } - - +{ + "extends": ["next/core-web-vitals", "next/typescript"] +} diff --git a/.gitignore b/.gitignore index b53673c..eb33024 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,10 @@ share # production /build +# PWA +/public/workbox-*.js +/public/sw.js + # misc .DS_Store *.pem diff --git a/public/sw.js b/public/sw.js index 00b36e2..79ea85f 100644 --- a/public/sw.js +++ b/public/sw.js @@ -1,16 +1 @@ -// public/sw.js -const CACHE_NAME = 'zitacode-v3'; -const urlsToCache = ['/', '/index.html', '/icons/icon-192x192.png', - '/icons/icon-512x512.png', '/manifest.json']; - -self.addEventListener('install', (event) => { - event.waitUntil( - caches.open(CACHE_NAME).then((cache) => cache.addAll(urlsToCache)) - ); -}); - -self.addEventListener('fetch', (event) => { - event.respondWith( - caches.match(event.request).then((response) => response || fetch(event.request)) - ); -}); \ No newline at end of file +if(!self.define){let e,s={};const i=(i,c)=>(i=new URL(i+".js",c).href,s[i]||new Promise((s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()})).then((()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e})));self.define=(c,n)=>{const a=e||("document"in self?document.currentScript.src:"")||location.href;if(s[a])return;let r={};const t=e=>i(e,a),f={module:{uri:a},exports:r,require:t};s[a]=Promise.all(c.map((e=>f[e]||t(e)))).then((e=>(n(...e),r)))}}define(["./workbox-cb477421"],(function(e){"use strict";importScripts(),self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"/Image...webp",revision:"9ff870e78684974d2dded45ee3fba2a8"},{url:"/_next/app-build-manifest.json",revision:"87b189fe756ec9123b620947a4dfc4b9"},{url:"/_next/static/chunks/151-9e5e4cee48ac085d.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/30-b2c34408ececc304.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/340-1a223f41cb1cc8bb.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/411.9485f8254db3babd.js",revision:"9485f8254db3babd"},{url:"/_next/static/chunks/413-b3166f9998e152c4.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/465-1015b3079c704cc7.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/4bd1b696-e360e80a2d631ddb.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/642.309e2bb26d436a0f.js",revision:"309e2bb26d436a0f"},{url:"/_next/static/chunks/684-f464ef37aa466213.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/874-61418153cf92241f.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/app/(root)/page-a2327fb32ec05b59.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/app/_not-found/page-dc47581ec9528fd0.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/app/about/page-72e6b7409277cac0.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/app/api/gemini/review/route-56c3fcea48c46f8f.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/app/layout-b3328d1e442a1195.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/app/privacy/page-858f3e9c626a4e7d.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/app/snippets/page-f8f7659d39a6b605.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/app/support/page-626a32bdd8a8205a.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/app/support/quiz/page-36c4c1f070f5dd84.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/framework-bc1e13f942cda702.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/main-app-56e7dc9f7e5a9ae4.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/main-cf97dd160721f15f.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/pages/_app-8e94039938385921.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/pages/_error-7b2d139042a6a5ab.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/chunks/polyfills-42372ed130431b0a.js",revision:"846118c33b2c0e922d7b3a7676f81f6f"},{url:"/_next/static/chunks/webpack-0c2bdaff79e81a55.js",revision:"83_WSYsD3lX7vq8MNs_1m"},{url:"/_next/static/css/d22210e5f0ae351f.css",revision:"d22210e5f0ae351f"},{url:"/_next/static/media/4473ecc91f70f139-s.p.woff",revision:"78e6fc13ea317b55ab0bd6dc4849c110"},{url:"/_next/static/media/463dafcda517f24f-s.p.woff",revision:"cbeb6d2d96eaa268b4b5beb0b46d9632"},{url:"/bash.png",revision:"a88dc418a22a522ee77c636ac8c42376"},{url:"/c.png",revision:"e52c7c056c750e0e4d557f6a96cd19f8"},{url:"/cpp.png",revision:"c2a1f6e84e1bef46c8d91ed0cdb3c4a3"},{url:"/csharp.png",revision:"d9663f0444da72d399029a38df43197a"},{url:"/go.png",revision:"cc5b616a37658256148e81f07c8ed078"},{url:"/icons/icon-192x192.png",revision:"558edf62cc4829422507df699209c70f"},{url:"/icons/icon-512x512.png",revision:"46f4862178b0cde340cc0ffa4bf3088a"},{url:"/icons/splash-640x1136.png",revision:"9ce3966bc4ff3d92f3a688778af1ac0e"},{url:"/java.png",revision:"8b9bb10de4c57bbd3407536f5d261d64"},{url:"/javascript.png",revision:"0cded3a3276425911d55a2552bf361bf"},{url:"/manifest.json",revision:"a5e802223c43650c9da271fd2d284e1f"},{url:"/next.svg",revision:"8e061864f388b47f33a1c3780831193e"},{url:"/python.png",revision:"4798618fb654d48e05c9e20f6a701909"},{url:"/ruby.png",revision:"c59227bbc1e588989f23820c27483f78"},{url:"/rust.png",revision:"481378d455938db5fe0f5f0b098e099f"},{url:"/swift.png",revision:"b143441a65536d2f75f3f3aae9361580"},{url:"/typescript.png",revision:"4ec83d0f7fc81fb66e5896647f52cf47"},{url:"/vercel.svg",revision:"0322fd3fe05569b1bb28b1fde15f3046"},{url:"/vercel1.svg",revision:"8561c544df1ec7687c1e3668fb5c198a"}],{ignoreURLParametersMatching:[]}),e.cleanupOutdatedCaches(),e.registerRoute("/",new e.NetworkFirst({cacheName:"start-url",plugins:[{cacheWillUpdate:async({request:e,response:s,event:i,state:c})=>s&&"opaqueredirect"===s.type?new Response(s.body,{status:200,statusText:"OK",headers:s.headers}):s}]}),"GET"),e.registerRoute(/^https?.*/,new e.NetworkFirst({cacheName:"offlineCache",plugins:[new e.ExpirationPlugin({maxEntries:200})]}),"GET")})); diff --git a/src/app/(root)/_components/SignInPopup.tsx b/src/app/(root)/_components/SignInPopup.tsx new file mode 100644 index 0000000..7254f9f --- /dev/null +++ b/src/app/(root)/_components/SignInPopup.tsx @@ -0,0 +1,93 @@ +"use client"; + +import { useState, useEffect } from "react"; +import { SignedOut, SignInButton } from "@clerk/nextjs"; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog"; +import { Button } from "@/components/ui/button"; +import { Code2, X } from "lucide-react"; + +function SignInPopup() { + const [isOpen, setIsOpen] = useState(false); + const [hasShown, setHasShown] = useState(false); + + useEffect(() => { + // Check if popup has been shown before + const popupShown = localStorage.getItem("zitacode-signin-popup-shown"); + + if (!popupShown && !hasShown) { + // Show popup after a brief delay to allow page to load + const timer = setTimeout(() => { + setIsOpen(true); + setHasShown(true); + }, 1500); + + return () => clearTimeout(timer); + } + }, [hasShown]); + + const handleClose = () => { + setIsOpen(false); + // Mark popup as shown so it doesn't appear again in this session + localStorage.setItem("zitacode-signin-popup-shown", "true"); + }; + + const handleRemindLater = () => { + setIsOpen(false); + // Don't set localStorage so it can show again in future sessions + }; + + return ( + + + + +
+ +
+ + Welcome to ZitaCode! + + + Sign in to unlock the full power of our code editor. Get access to advanced features, save your projects, and join our community of developers. + +
+ +
+ + + + +
+ + +
+
+ + +
+
+
+ ); +} + +export default SignInPopup; \ No newline at end of file diff --git a/src/app/(root)/page.tsx b/src/app/(root)/page.tsx index 4e5a592..69c4bde 100644 --- a/src/app/(root)/page.tsx +++ b/src/app/(root)/page.tsx @@ -2,12 +2,14 @@ import EditorPanel from "./_components/EditorPanel"; import Header from "./_components/Header" import NetworkStatusToast from "./_components/NetworkStatusToast"; import OutputPanel from "./_components/OutputPanel"; +import SignInPopup from "./_components/SignInPopup"; export default function Home() { return (
+