Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39fa9ef19d | ||
|
|
ec7d0e496c | ||
|
|
67930e0c1a |
@ -4,15 +4,21 @@ import { createClient } from "@/lib/supabase/server"
|
|||||||
export async function GET(request: Request) {
|
export async function GET(request: Request) {
|
||||||
const { searchParams, origin } = new URL(request.url)
|
const { searchParams, origin } = new URL(request.url)
|
||||||
const code = searchParams.get("code")
|
const code = searchParams.get("code")
|
||||||
|
const type = searchParams.get("type")
|
||||||
const next = searchParams.get("next") ?? "/feed"
|
const next = searchParams.get("next") ?? "/feed"
|
||||||
|
|
||||||
|
// If this is a password recovery flow, handle it specifically
|
||||||
|
if (type === 'recovery') {
|
||||||
|
return NextResponse.redirect(`${process.env.NEXT_PUBLIC_SITE_URL}/auth/update-password`)
|
||||||
|
}
|
||||||
|
|
||||||
if (code) {
|
if (code) {
|
||||||
const supabase = await createClient()
|
const supabase = await createClient()
|
||||||
const { error } = await supabase.auth.exchangeCodeForSession(code)
|
const { error } = await supabase.auth.exchangeCodeForSession(code)
|
||||||
if (!error) {
|
if (!error) {
|
||||||
return NextResponse.redirect(`${origin}${next}`)
|
return NextResponse.redirect(`${process.env.NEXT_PUBLIC_SITE_URL}${next}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NextResponse.redirect(`${origin}/auth/error`)
|
return NextResponse.redirect(`${process.env.NEXT_PUBLIC_SITE_URL}/auth/error`)
|
||||||
}
|
}
|
||||||
@ -6,15 +6,17 @@ import { useState } from "react"
|
|||||||
import { useRouter } from "next/navigation"
|
import { useRouter } from "next/navigation"
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import { createClient } from "@/lib/supabase/client"
|
import { createClient } from "@/lib/supabase/client"
|
||||||
import { Film, Eye, Loader2 } from "lucide-react"
|
import { Film, Eye, Loader2, Mail } from "lucide-react"
|
||||||
import { useLanguage } from "@/contexts/LanguageContext"
|
import { useLanguage } from "@/contexts/LanguageContext"
|
||||||
import { LanguageToggle } from "@/components/language-toggle"
|
import { LanguageToggle } from "@/components/language-toggle"
|
||||||
|
import { toast } from "sonner"
|
||||||
|
|
||||||
export default function LoginPage() {
|
export default function LoginPage() {
|
||||||
const [email, setEmail] = useState("")
|
const [email, setEmail] = useState("")
|
||||||
const [password, setPassword] = useState("")
|
const [password, setPassword] = useState("")
|
||||||
const [error, setError] = useState<string | null>(null)
|
const [error, setError] = useState<string | null>(null)
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [resetLoading, setResetLoading] = useState(false)
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { t } = useLanguage()
|
const { t } = useLanguage()
|
||||||
|
|
||||||
@ -22,6 +24,8 @@ export default function LoginPage() {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
setError(null)
|
setError(null)
|
||||||
|
|
||||||
|
console.log("Attempting login for:", email);
|
||||||
|
|
||||||
const supabase = createClient()
|
const supabase = createClient()
|
||||||
const { error } = await supabase.auth.signInWithPassword({
|
const { error } = await supabase.auth.signInWithPassword({
|
||||||
@ -30,7 +34,8 @@ export default function LoginPage() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
setError(t("auth.invalidCredentials"))
|
console.error("Login error:", error);
|
||||||
|
setError(error.message)
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -39,6 +44,31 @@ export default function LoginPage() {
|
|||||||
router.refresh()
|
router.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleResetPassword() {
|
||||||
|
if (!email) {
|
||||||
|
setError("Bitte gib deine E-Mail-Adresse oben ein.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setResetLoading(true)
|
||||||
|
setError(null)
|
||||||
|
|
||||||
|
const supabase = createClient()
|
||||||
|
// Important: The redirectTo here should be the URL that Supabase sends the user to after they click the link in their email.
|
||||||
|
// If we want it to hit our app/auth/callback, it handles the recovery flow via the new logic.
|
||||||
|
const { error } = await supabase.auth.resetPasswordForEmail(email, {
|
||||||
|
redirectTo: `${process.env.NEXT_PUBLIC_SITE_URL}/auth/callback?type=recovery`,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
setError(error.message)
|
||||||
|
setResetLoading(false)
|
||||||
|
} else {
|
||||||
|
toast.success("E-Mail zum Zurücksetzen des Passworts wurde gesendet.")
|
||||||
|
setResetLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="flex min-h-dvh flex-col items-center justify-center px-6">
|
<main className="flex min-h-dvh flex-col items-center justify-center px-6">
|
||||||
<div className="w-full max-w-sm">
|
<div className="w-full max-w-sm">
|
||||||
@ -108,6 +138,19 @@ export default function LoginPage() {
|
|||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={handleResetPassword}
|
||||||
|
disabled={resetLoading}
|
||||||
|
className="mt-4 flex w-full items-center justify-center gap-2 text-sm text-muted-foreground hover:text-primary transition-colors disabled:opacity-50"
|
||||||
|
>
|
||||||
|
{resetLoading ? (
|
||||||
|
<Loader2 className="h-4 w-4 animate-spin" />
|
||||||
|
) : (
|
||||||
|
<Mail className="h-4 w-4" />
|
||||||
|
)}
|
||||||
|
Passwort vergessen?
|
||||||
|
</button>
|
||||||
|
|
||||||
<p className="mt-6 text-center text-sm text-muted-foreground">
|
<p className="mt-6 text-center text-sm text-muted-foreground">
|
||||||
{t("auth.dontHaveAccount")}{" "}
|
{t("auth.dontHaveAccount")}{" "}
|
||||||
<Link href="/auth/sign-up" className="font-medium text-primary hover:underline">
|
<Link href="/auth/sign-up" className="font-medium text-primary hover:underline">
|
||||||
@ -117,4 +160,4 @@ export default function LoginPage() {
|
|||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
57
app/auth/update-password/page.tsx
Normal file
57
app/auth/update-password/page.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import React, { useState } from "react"
|
||||||
|
import { useRouter } from "next/navigation"
|
||||||
|
import { createClient } from "@/lib/supabase/client"
|
||||||
|
import { Loader2 } from "lucide-react"
|
||||||
|
import { toast } from "sonner"
|
||||||
|
|
||||||
|
export default function UpdatePasswordPage() {
|
||||||
|
const [password, setPassword] = useState("")
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const router = useRouter()
|
||||||
|
const supabase = createClient()
|
||||||
|
|
||||||
|
async function handleUpdatePassword(e: React.FormEvent) {
|
||||||
|
e.preventDefault()
|
||||||
|
setLoading(true)
|
||||||
|
|
||||||
|
const { error } = await supabase.auth.updateUser({
|
||||||
|
password: password,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
toast.error(error.message)
|
||||||
|
} else {
|
||||||
|
toast.success("Passwort erfolgreich geändert.")
|
||||||
|
router.push("/feed")
|
||||||
|
router.refresh()
|
||||||
|
}
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main className="flex min-h-dvh flex-col items-center justify-center px-6">
|
||||||
|
<div className="w-full max-w-sm">
|
||||||
|
<h1 className="mb-6 text-2xl font-bold">Neues Passwort festlegen</h1>
|
||||||
|
<form onSubmit={handleUpdatePassword} className="flex flex-col gap-4">
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
value={password}
|
||||||
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
|
placeholder="Neues Passwort"
|
||||||
|
required
|
||||||
|
className="h-12 w-full rounded-lg border border-input bg-background px-4 text-sm"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={loading}
|
||||||
|
className="flex h-12 w-full items-center justify-center gap-2 rounded-lg bg-primary font-semibold text-primary-foreground disabled:opacity-50"
|
||||||
|
>
|
||||||
|
{loading ? <Loader2 className="h-5 w-5 animate-spin" /> : "Passwort speichern"}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -6,7 +6,7 @@ export async function GET(request: NextRequest) {
|
|||||||
const state = searchParams.get('state')
|
const state = searchParams.get('state')
|
||||||
|
|
||||||
if (!code) {
|
if (!code) {
|
||||||
return NextResponse.redirect('http://localhost:3000/auth/error?error=oauth_code_missing')
|
return NextResponse.redirect(new URL('/oauth/error?error=oauth_code_missing', request.url))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle OAuth callback for MCP server
|
// Handle OAuth callback for MCP server
|
||||||
@ -21,22 +21,22 @@ export async function GET(request: NextRequest) {
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
code,
|
code,
|
||||||
state,
|
state,
|
||||||
redirect_uri: 'http://localhost:3000/oauth/consent'
|
redirect_uri: new URL('/oauth/consent', request.url).toString()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const result = await response.json()
|
const result = await response.json()
|
||||||
|
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
return NextResponse.redirect(`http://localhost:3000/auth/error?error=${result.error}`)
|
return NextResponse.redirect(new URL(`/oauth/error?error=${result.error}`, request.url))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store tokens securely (in production, use proper session management)
|
// Store tokens securely (in production, use proper session management)
|
||||||
// For now, redirect back to app
|
// For now, redirect back to app
|
||||||
return NextResponse.redirect('http://localhost:3000/auth/success?mcp_configured=true')
|
return NextResponse.redirect(new URL('/oauth/success?mcp_configured=true', request.url))
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('OAuth callback error:', error)
|
console.error('OAuth callback error:', error)
|
||||||
return NextResponse.redirect('http://localhost:3000/auth/error?error=oauth_callback_failed')
|
return NextResponse.redirect(new URL('/oauth/error?error=oauth_callback_failed', request.url))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,8 +1,15 @@
|
|||||||
import { createBrowserClient } from '@supabase/ssr'
|
import { createBrowserClient } from '@supabase/ssr'
|
||||||
|
|
||||||
export function createClient() {
|
export function createClient() {
|
||||||
|
const url = process.env.NEXT_PUBLIC_SUPABASE_URL || "https://ekbpexbhuochrplzorce.supabase.co";
|
||||||
|
const key = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || "sb_publishable__UII_iKx3pgvLQvc1xrN1w_qnwP6JOv" || process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY;
|
||||||
|
|
||||||
|
if (!url || !key) {
|
||||||
|
console.error("Supabase config missing!", { url: !!url, key: !!key });
|
||||||
|
}
|
||||||
|
|
||||||
return createBrowserClient(
|
return createBrowserClient(
|
||||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
url!,
|
||||||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
key!,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,8 +7,8 @@ export async function updateSession(request: NextRequest) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const supabase = createServerClient(
|
const supabase = createServerClient(
|
||||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
process.env.NEXT_PUBLIC_SUPABASE_URL || "https://ekbpexbhuochrplzorce.supabase.co"!,
|
||||||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || "sb_publishable__UII_iKx3pgvLQvc1xrN1w_qnwP6JOv" || process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY!,
|
||||||
{
|
{
|
||||||
cookies: {
|
cookies: {
|
||||||
getAll() {
|
getAll() {
|
||||||
|
|||||||
@ -5,8 +5,8 @@ export async function createClient() {
|
|||||||
const cookieStore = await cookies()
|
const cookieStore = await cookies()
|
||||||
|
|
||||||
return createServerClient(
|
return createServerClient(
|
||||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
process.env.NEXT_PUBLIC_SUPABASE_URL || "https://ekbpexbhuochrplzorce.supabase.co"!,
|
||||||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || "sb_publishable__UII_iKx3pgvLQvc1xrN1w_qnwP6JOv" || process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY!,
|
||||||
{
|
{
|
||||||
cookies: {
|
cookies: {
|
||||||
getAll() {
|
getAll() {
|
||||||
|
|||||||
@ -7,6 +7,6 @@ export async function middleware(request: NextRequest) {
|
|||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
matcher: [
|
matcher: [
|
||||||
'/((?!_next/static|_next/image|favicon.ico|manifest.json|icons/.*|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
|
'/((?!_next/static|_next/image|favicon.ico|manifest.json|sw.js|icons/.*|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
3
next-env.d.ts
vendored
3
next-env.d.ts
vendored
@ -1,5 +1,6 @@
|
|||||||
/// <reference types="next" />
|
/// <reference types="next" />
|
||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
|
import "./.next/types/routes.d.ts";
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
|
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||||
|
|||||||
@ -13,6 +13,11 @@ const nextConfig = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
devIndicators: {
|
||||||
|
appIsrStatus: false,
|
||||||
|
},
|
||||||
|
// Allow host for dev server to fix HMR/WebSocket issues
|
||||||
|
allowedDevOrigins: ['infocusmovieapp-3455.dev.appwizzy.dev'],
|
||||||
}
|
}
|
||||||
|
|
||||||
export default nextConfig
|
export default nextConfig
|
||||||
7183
package-lock.json
generated
7183
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
59
package.json
59
package.json
@ -4,32 +4,79 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "tsx server.ts",
|
"dev": "next dev -H 0.0.0.0 -p 3001",
|
||||||
"build": "vite build",
|
"build": "next build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"clean": "rm -rf dist",
|
"clean": "rm -rf dist",
|
||||||
"lint": "tsc --noEmit"
|
"lint": "tsc --noEmit",
|
||||||
|
"start": "next dev -H 0.0.0.0 -p 3001"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@google/genai": "^1.29.0",
|
"@google/genai": "^1.29.0",
|
||||||
|
"@radix-ui/react-accordion": "^1.2.12",
|
||||||
|
"@radix-ui/react-alert-dialog": "^1.1.15",
|
||||||
|
"@radix-ui/react-aspect-ratio": "^1.1.8",
|
||||||
|
"@radix-ui/react-avatar": "^1.1.11",
|
||||||
|
"@radix-ui/react-checkbox": "^1.3.3",
|
||||||
|
"@radix-ui/react-collapsible": "^1.1.12",
|
||||||
|
"@radix-ui/react-context-menu": "^2.2.16",
|
||||||
|
"@radix-ui/react-dialog": "^1.1.15",
|
||||||
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||||
|
"@radix-ui/react-hover-card": "^1.1.15",
|
||||||
|
"@radix-ui/react-label": "^2.1.8",
|
||||||
|
"@radix-ui/react-menubar": "^1.1.16",
|
||||||
|
"@radix-ui/react-navigation-menu": "^1.2.14",
|
||||||
|
"@radix-ui/react-popover": "^1.1.15",
|
||||||
|
"@radix-ui/react-progress": "^1.1.8",
|
||||||
|
"@radix-ui/react-radio-group": "^1.3.8",
|
||||||
|
"@radix-ui/react-scroll-area": "^1.2.10",
|
||||||
|
"@radix-ui/react-select": "^2.2.6",
|
||||||
|
"@radix-ui/react-separator": "^1.1.8",
|
||||||
|
"@radix-ui/react-slider": "^1.3.6",
|
||||||
|
"@radix-ui/react-slot": "^1.2.4",
|
||||||
|
"@radix-ui/react-switch": "^1.2.6",
|
||||||
|
"@radix-ui/react-tabs": "^1.1.13",
|
||||||
|
"@radix-ui/react-toast": "^1.2.15",
|
||||||
|
"@radix-ui/react-toggle": "^1.1.10",
|
||||||
|
"@radix-ui/react-toggle-group": "^1.1.11",
|
||||||
|
"@radix-ui/react-tooltip": "^1.2.8",
|
||||||
|
"@supabase/ssr": "^0.10.0",
|
||||||
"@supabase/supabase-js": "^2.99.1",
|
"@supabase/supabase-js": "^2.99.1",
|
||||||
"@tailwindcss/vite": "^4.1.14",
|
"@tailwindcss/vite": "^4.1.14",
|
||||||
|
"@types/react": "^19.2.14",
|
||||||
|
"@types/react-dom": "^19.2.3",
|
||||||
"@vitejs/plugin-react": "^5.0.4",
|
"@vitejs/plugin-react": "^5.0.4",
|
||||||
|
"class-variance-authority": "^0.7.1",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"cmdk": "^1.1.1",
|
||||||
|
"date-fns": "3.6.0",
|
||||||
"dotenv": "^17.3.1",
|
"dotenv": "^17.3.1",
|
||||||
|
"embla-carousel-react": "^8.6.0",
|
||||||
"express": "^4.22.1",
|
"express": "^4.22.1",
|
||||||
|
"input-otp": "^1.4.2",
|
||||||
"lucide-react": "^0.546.0",
|
"lucide-react": "^0.546.0",
|
||||||
"motion": "^12.23.24",
|
"motion": "^12.23.24",
|
||||||
|
"next": "^16.2.3",
|
||||||
|
"next-themes": "^0.4.6",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
|
||||||
"react-day-picker": "8.10.1",
|
"react-day-picker": "8.10.1",
|
||||||
"date-fns": "3.6.0",
|
"react-dom": "^19.0.0",
|
||||||
|
"react-hook-form": "^7.72.1",
|
||||||
|
"react-resizable-panels": "^4.9.0",
|
||||||
|
"recharts": "^3.8.1",
|
||||||
|
"sonner": "^2.0.7",
|
||||||
|
"tailwind-merge": "^3.5.0",
|
||||||
|
"tailwindcss-animate": "^1.0.7",
|
||||||
|
"vaul": "^1.1.2",
|
||||||
"vite": "^6.2.0"
|
"vite": "^6.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@tailwindcss/postcss": "^4.2.2",
|
||||||
"@types/express": "^4.17.25",
|
"@types/express": "^4.17.25",
|
||||||
"@types/node": "^22.14.0",
|
"@types/node": "^22.14.0",
|
||||||
"autoprefixer": "^10.4.21",
|
"autoprefixer": "^10.4.21",
|
||||||
"tailwindcss": "^4.1.14",
|
"postcss": "^8.4.49",
|
||||||
|
"tailwindcss": "^3.4.17",
|
||||||
"tsx": "^4.21.0",
|
"tsx": "^4.21.0",
|
||||||
"typescript": "~5.8.2",
|
"typescript": "~5.8.2",
|
||||||
"vite": "^6.2.0"
|
"vite": "^6.2.0"
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
const config = {
|
const config = {
|
||||||
plugins: {
|
plugins: {
|
||||||
tailwindcss: {},
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
public/sw.js
14
public/sw.js
@ -39,8 +39,10 @@ self.addEventListener("fetch", (event) => {
|
|||||||
(cached) =>
|
(cached) =>
|
||||||
cached ||
|
cached ||
|
||||||
fetch(event.request).then((response) => {
|
fetch(event.request).then((response) => {
|
||||||
const clone = response.clone()
|
if (response.status === 200 && event.request.method === 'GET') {
|
||||||
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, clone))
|
const clone = response.clone()
|
||||||
|
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, clone))
|
||||||
|
}
|
||||||
return response
|
return response
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -52,10 +54,12 @@ self.addEventListener("fetch", (event) => {
|
|||||||
event.respondWith(
|
event.respondWith(
|
||||||
fetch(event.request)
|
fetch(event.request)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
const clone = response.clone()
|
if (response.status === 200 && event.request.method === 'GET') {
|
||||||
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, clone))
|
const clone = response.clone()
|
||||||
|
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, clone))
|
||||||
|
}
|
||||||
return response
|
return response
|
||||||
})
|
})
|
||||||
.catch(() => caches.match(event.request))
|
.catch(() => caches.match(event.request))
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -15,7 +15,7 @@
|
|||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"jsx": "preserve",
|
"jsx": "react-jsx",
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user