diff --git a/Dockerfile b/Dockerfile index 931bc9e..77e48e5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,11 @@ -FROM node:alpine -MAINTAINER Alexander Kern +FROM node:lts-alpine +RUN apk add --no-cache pnpm + +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install COPY . ./ -RUN npm install && npm run build +RUN pnpm build ENV NODE_ENV production EXPOSE 80 diff --git a/package.json b/package.json index e1f99da..0968b2a 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,10 @@ "build": "next build", "start": "next start", "start:peerjs": "./bin/peerjs.js", - "lint": "eslint 'src/**/*.ts[x]'" + "lint": "eslint 'src/**/*.ts[x]'", + "docker:build": "docker build -t kern/filepizza .", + "format": "prettier --write \"src/**/*.{ts,tsx}\"", + "format:check": "prettier --check \"src/**/*.{ts,tsx}\"" }, "repository": { "type": "git", @@ -37,7 +40,6 @@ "react-qr-code": "^2.0.15", "streamsaver": "^2.0.6", "tailwindcss": "^3.4.10", - "twilio": "^2.11.1", "web-streams-polyfill": "^3.3.3", "webrtcsupport": "^2.2.0", "zod": "^3.23.8" diff --git a/public/fonts/LobsterTwo.woff2 b/public/fonts/LobsterTwo.woff2 deleted file mode 100755 index ee9640e..0000000 Binary files a/public/fonts/LobsterTwo.woff2 and /dev/null differ diff --git a/public/fonts/QuicksandBold.woff2 b/public/fonts/QuicksandBold.woff2 deleted file mode 100755 index f61bc08..0000000 Binary files a/public/fonts/QuicksandBold.woff2 and /dev/null differ diff --git a/public/fonts/QuicksandLight.woff2 b/public/fonts/QuicksandLight.woff2 deleted file mode 100755 index 3fdc01c..0000000 Binary files a/public/fonts/QuicksandLight.woff2 and /dev/null differ diff --git a/public/fonts/QuicksandNormal.woff2 b/public/fonts/QuicksandNormal.woff2 deleted file mode 100755 index 572e6d6..0000000 Binary files a/public/fonts/QuicksandNormal.woff2 and /dev/null differ diff --git a/public/fonts/fonts.css b/public/fonts/fonts.css deleted file mode 100755 index f32cdc8..0000000 --- a/public/fonts/fonts.css +++ /dev/null @@ -1,32 +0,0 @@ -/* latin */ -@font-face { - font-family: 'Lobster Two'; - font-style: normal; - font-weight: 400; - src: local('Lobster Two'), local('LobsterTwo'), url(./LobsterTwo.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; -} -/* latin */ -@font-face { - font-family: 'Quicksand'; - font-style: normal; - font-weight: 300; - src: local('Quicksand Light'), local('Quicksand-Light'), url(./QuicksandLight.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; -} -/* latin */ -@font-face { - font-family: 'Quicksand'; - font-style: normal; - font-weight: 400; - src: local('Quicksand Regular'), local('Quicksand-Regular'), url(./QuicksandNormal.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; -} -/* latin */ -@font-face { - font-family: 'Quicksand'; - font-style: normal; - font-weight: 700; - src: local('Quicksand Bold'), local('Quicksand-Bold'), url(./QuicksandBold.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; -} diff --git a/src/app/api/create/route.ts b/src/app/api/create/route.ts index 6dc6f0a..d160e89 100644 --- a/src/app/api/create/route.ts +++ b/src/app/api/create/route.ts @@ -1,16 +1,7 @@ -import { NextRequest, NextResponse } from 'next/server' +import { NextResponse } from 'next/server' import { Channel, channelRepo } from '../../../channel' -export async function POST(request: NextRequest): Promise { - const { uploaderPeerID } = await request.json() - - if (!uploaderPeerID) { - return NextResponse.json( - { error: 'uploaderPeerID is required' }, - { status: 400 }, - ) - } - - const channel: Channel = await channelRepo.create(uploaderPeerID) +export async function POST(): Promise { + const channel: Channel = await channelRepo.create() return NextResponse.json(channel) } diff --git a/src/app/api/destroy/route.ts b/src/app/api/destroy/route.ts index 217d601..a3a240d 100644 --- a/src/app/api/destroy/route.ts +++ b/src/app/api/destroy/route.ts @@ -2,14 +2,18 @@ import { NextRequest, NextResponse } from 'next/server' import { channelRepo } from '../../../channel' export async function POST(request: NextRequest): Promise { - const { slug } = await request.json() + const { slug, secret } = await request.json() if (!slug) { return NextResponse.json({ error: 'Slug is required' }, { status: 400 }) } + if (!secret) { + return NextResponse.json({ error: 'Secret is required' }, { status: 400 }) + } + try { - await channelRepo.destroy(slug) + await channelRepo.destroy(slug, secret) return NextResponse.json({ success: true }, { status: 200 }) } catch (error) { return NextResponse.json( diff --git a/src/app/api/offer/route.ts b/src/app/api/offer/route.ts new file mode 100644 index 0000000..902271c --- /dev/null +++ b/src/app/api/offer/route.ts @@ -0,0 +1,17 @@ +import { NextRequest, NextResponse } from 'next/server' +import { channelRepo } from '../../../channel' + +export async function POST(request: NextRequest): Promise { + const { slug, offer } = await request.json() + + if (!slug) { + return NextResponse.json({ error: 'Slug is required' }, { status: 400 }) + } + + if (!offer) { + return NextResponse.json({ error: 'Offer is required' }, { status: 400 }) + } + + await channelRepo.offer(slug, offer) + return NextResponse.json({ success: true }) +} diff --git a/src/app/api/renew/route.ts b/src/app/api/renew/route.ts index 0bed687..58ffd0b 100644 --- a/src/app/api/renew/route.ts +++ b/src/app/api/renew/route.ts @@ -2,12 +2,16 @@ import { NextRequest, NextResponse } from 'next/server' import { channelRepo } from '../../../channel' export async function POST(request: NextRequest): Promise { - const { slug } = await request.json() + const { slug, secret } = await request.json() if (!slug) { return NextResponse.json({ error: 'Slug is required' }, { status: 400 }) } - await channelRepo.renew(slug) - return NextResponse.json({ success: true }) + if (!secret) { + return NextResponse.json({ error: 'Secret is required' }, { status: 400 }) + } + + const offers = await channelRepo.renew(slug, secret) + return NextResponse.json({ success: true, offers }) } diff --git a/src/app/download/[...slug]/page.tsx b/src/app/download/[...slug]/page.tsx index c294d6c..8a8cad1 100644 --- a/src/app/download/[...slug]/page.tsx +++ b/src/app/download/[...slug]/page.tsx @@ -30,7 +30,7 @@ export default async function DownloadPage({ - + ) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index ba6e937..66e66cb 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -3,6 +3,7 @@ import Footer from '../components/Footer' import '../styles.css' import { ThemeProvider } from '../components/ThemeProvider' import { ModeToggle } from '../components/ModeToggle' +import FilePizzaQueryClientProvider from '../components/QueryClientProvider' export const metadata = { title: 'FilePizza • Your files, delivered.', @@ -29,9 +30,11 @@ export default function RootLayout({ -
{children}
-