Fixes
This commit is contained in:
45
Dockerfile
45
Dockerfile
@ -1,40 +1,19 @@
|
|||||||
# Install dependencies only when needed
|
# Base image
|
||||||
FROM node:20-alpine AS deps
|
FROM node:20
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# Install global Prisma CLI
|
# Set working directory
|
||||||
RUN npm install -g prisma
|
WORKDIR /app
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
COPY package.json package-lock.json* ./
|
COPY package.json package-lock.json ./
|
||||||
RUN npm ci
|
RUN npm install
|
||||||
|
|
||||||
# Copy only prisma schema to generate client early
|
# Copy the rest of the code
|
||||||
COPY prisma ./prisma/
|
COPY . .
|
||||||
RUN npx prisma generate
|
RUN npx prisma generate
|
||||||
|
|
||||||
# Builder image
|
# Expose the dev port
|
||||||
FROM node:20-alpine AS builder
|
EXPOSE 3000
|
||||||
WORKDIR /app
|
|
||||||
COPY --from=deps /app/node_modules ./node_modules
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# Build the app
|
# Run dev server
|
||||||
RUN npm run build
|
CMD ["npm", "run", "dev"]
|
||||||
|
|
||||||
# Production image
|
|
||||||
FROM node:20-alpine AS runner
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
ENV NODE_ENV production
|
|
||||||
|
|
||||||
# Copy necessary files
|
|
||||||
COPY --from=builder /app/public ./public
|
|
||||||
COPY --from=builder /app/.next ./.next
|
|
||||||
COPY --from=builder /app/node_modules ./node_modules
|
|
||||||
COPY --from=builder /app/package.json ./package.json
|
|
||||||
COPY --from=builder /app/prisma ./prisma
|
|
||||||
|
|
||||||
# Run migrations if needed
|
|
||||||
# CMD npx prisma migrate deploy && node .next/standalone/server.js
|
|
||||||
CMD node .next/standalone/server.js
|
|
||||||
|
@ -2,7 +2,6 @@ import ArtistInfoBox from "@/components/images/ArtistInfoBox";
|
|||||||
import GlowingImageWithToggle from "@/components/images/GlowingImageWithToggle";
|
import GlowingImageWithToggle from "@/components/images/GlowingImageWithToggle";
|
||||||
import ImageMetadataBox from "@/components/images/ImageMetadataBox";
|
import ImageMetadataBox from "@/components/images/ImageMetadataBox";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
import Link from "next/link";
|
|
||||||
|
|
||||||
export default async function ImagePage({ params }: { params: { gallerySlug: string, albumSlug: string, imageId: string } }) {
|
export default async function ImagePage({ params }: { params: { gallerySlug: string, albumSlug: string, imageId: string } }) {
|
||||||
const { imageId } = await params;
|
const { imageId } = await params;
|
||||||
@ -38,15 +37,15 @@ export default async function ImagePage({ params }: { params: { gallerySlug: str
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{resizedVariant &&
|
{resizedVariant &&
|
||||||
<Link href={`/raw/${image.id}`} passHref>
|
<GlowingImageWithToggle
|
||||||
<GlowingImageWithToggle
|
alt={image.imageName}
|
||||||
alt={image.imageName}
|
variant={resizedVariant}
|
||||||
variant={resizedVariant}
|
colors={image.colors}
|
||||||
colors={image.colors}
|
src={`/api/image/${resizedVariant.s3Key}`}
|
||||||
src={`/api/image/${resizedVariant.s3Key}`}
|
nsfw={image.nsfw}
|
||||||
nsfw={image.nsfw}
|
imageId={image.id}
|
||||||
/>
|
/>
|
||||||
</Link>
|
|
||||||
}
|
}
|
||||||
<section className="py-8 flex flex-col gap-4">
|
<section className="py-8 flex flex-col gap-4">
|
||||||
{image.artist && <ArtistInfoBox artist={image.artist} />}
|
{image.artist && <ArtistInfoBox artist={image.artist} />}
|
||||||
|
@ -5,7 +5,7 @@ import NextImage from "next/image";
|
|||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
|
|
||||||
export default async function RawImagePage({ params }: { params: { imageId: string } }) {
|
export default async function RawImagePage({ params }: { params: { imageId: string } }) {
|
||||||
const { imageId } = params;
|
const { imageId } = await params;
|
||||||
|
|
||||||
const image = await prisma.image.findUnique({
|
const image = await prisma.image.findUnique({
|
||||||
where: { id: imageId },
|
where: { id: imageId },
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { Color, ImageColor, ImageVariant } from "@/generated/prisma";
|
import { Color, ImageColor, ImageVariant } from "@/generated/prisma";
|
||||||
|
import Link from "next/link";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Label } from "../ui/label";
|
import { Label } from "../ui/label";
|
||||||
import { Switch } from "../ui/switch";
|
import { Switch } from "../ui/switch";
|
||||||
@ -12,22 +13,26 @@ type Props = {
|
|||||||
alt: string;
|
alt: string;
|
||||||
src: string;
|
src: string;
|
||||||
nsfw: boolean;
|
nsfw: boolean;
|
||||||
|
imageId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function GlowingImageWithToggle({ variant, colors, alt, src, nsfw }: Props) {
|
export default function GlowingImageWithToggle({ variant, colors, alt, src, nsfw, imageId }: Props) {
|
||||||
const [animate, setAnimate] = useState(true);
|
const [animate, setAnimate] = useState(true);
|
||||||
const [revealed, setRevealed] = useState(!nsfw)
|
const [revealed, setRevealed] = useState(!nsfw)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative w-full max-w-fit">
|
<div className="relative w-full max-w-fit">
|
||||||
<GlowingImageBorder
|
|
||||||
alt={alt}
|
<Link href={`/raw/${imageId}`} passHref>
|
||||||
variant={variant}
|
<GlowingImageBorder
|
||||||
colors={colors}
|
alt={alt}
|
||||||
src={src}
|
variant={variant}
|
||||||
animate={animate}
|
colors={colors}
|
||||||
revealed={revealed}
|
src={src}
|
||||||
/>
|
animate={animate}
|
||||||
|
revealed={revealed}
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
|
||||||
<div className="flex flex-col items-center gap-4 pt-8">
|
<div className="flex flex-col items-center gap-4 pt-8">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
@ -36,14 +41,16 @@ export default function GlowingImageWithToggle({ variant, colors, alt, src, nsfw
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{nsfw && (
|
{
|
||||||
<div className="flex flex-col items-center gap-4 pt-8">
|
nsfw && (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex flex-col items-center gap-4 pt-8">
|
||||||
<Switch id="animate" checked={revealed} onCheckedChange={setRevealed} />
|
<div className="flex items-center gap-2">
|
||||||
<Label htmlFor="animate">Reveal NSFW</Label>
|
<Switch id="animate" checked={revealed} onCheckedChange={setRevealed} />
|
||||||
|
<Label htmlFor="animate">Reveal NSFW</Label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)
|
||||||
)}
|
}
|
||||||
</div>
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user