diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile index 9e6311c2..d950b304 100644 --- a/apps/web/Dockerfile +++ b/apps/web/Dockerfile @@ -1,17 +1,71 @@ -# -FROM node:18-alpine +FROM node:18-alpine AS base -# -WORKDIR /usr/learnhouse/front +# Install dependencies only when needed +FROM base AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat +WORKDIR /app -# -COPY package.json /usr/learnhouse/front/package.json +# Install dependencies based on the preferred package manager +COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ +RUN \ + if [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \ + else echo "Lockfile not found." && exit 1; \ + fi -# -RUN npm install -# -COPY ./ /usr/learnhouse +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . -# -CMD ["npm", "run", "dev"] \ No newline at end of file +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +# ENV NEXT_TELEMETRY_DISABLED 1 + +# Remove .env files from the final image +# This is a good practice to avoid leaking sensitive data +# Learn more about it in the Next.js documentation: https://nextjs.org/docs/basic-features/environment-variables +RUN rm -f .env* + +RUN \ + if [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \ + else echo "Lockfile not found." && exit 1; \ + fi + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +# Install curl +RUN apk add --no-cache curl + +ENV NODE_ENV production +# Uncomment the following line in case you want to disable telemetry during runtime. +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public + +# Set the correct permission for prerender cache +RUN mkdir .next +RUN chown nextjs:nodejs .next + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT 3000 + +# server.js is created by next build from the standalone output +# https://nextjs.org/docs/pages/api-reference/next-config-js/output +CMD HOSTNAME="0.0.0.0" node server.js \ No newline at end of file diff --git a/apps/web/app/api/revalidate/route.ts b/apps/web/app/api/revalidate/route.ts deleted file mode 100644 index e0645121..00000000 --- a/apps/web/app/api/revalidate/route.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { NextRequest, NextResponse } from 'next/server' -import { revalidateTag } from 'next/cache' - -export async function GET(request: NextRequest) { - const tag: any = request.nextUrl.searchParams.get('tag') - revalidateTag(tag) - - return NextResponse.json( - { revalidated: true, now: Date.now(), tag }, - { - status: 200, - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - } - ) -} diff --git a/apps/web/app/global-error.tsx b/apps/web/app/global-error.tsx deleted file mode 100644 index 451e8d52..00000000 --- a/apps/web/app/global-error.tsx +++ /dev/null @@ -1,24 +0,0 @@ -'use client' - -import * as Sentry from '@sentry/nextjs' -import NextError from 'next/error' -import { useEffect } from 'react' - -export default function GlobalError({ - error, -}: { - error: Error & { digest?: string } -}) { - useEffect(() => { - Sentry.captureException(error) - }, [error]) - - return ( - - - {/* This is the default Next.js error component but it doesn't allow omitting the statusCode property yet. */} - - - - ) -} diff --git a/apps/web/components/Objects/Modals/Feedback/Feedback.tsx b/apps/web/components/Objects/Modals/Feedback/Feedback.tsx deleted file mode 100644 index 311f0a8d..00000000 --- a/apps/web/components/Objects/Modals/Feedback/Feedback.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import FormLayout, { - ButtonBlack, - Flex, - FormField, - FormLabel, - FormMessage, - Textarea, -} from '@components/StyledElements/Form/Form' -import { BarLoader } from 'react-spinners' -import * as Form from '@radix-ui/react-form' -import React, { useState } from 'react' -import * as Sentry from '@sentry/browser' -import { CheckCircleIcon } from 'lucide-react' -import { useSession } from '@components/Contexts/SessionContext' - -export const FeedbackModal = (user: any) => { - const session = useSession() as any - - const [isSubmitting, setIsSubmitting] = useState(false) - const [view, setView] = useState<'feedbackForm' | 'success'>('feedbackForm') - const [feedbackMessage, setFeedbackMessage] = useState('') - - const handleSubmit = async (e: any) => { - e.preventDefault() - setIsSubmitting(true) - - const user = session.user ? session.user : null - const eventId = Sentry.captureMessage( - `Feedback from ${user ? user.email : 'Anonymous'} - ${feedbackMessage}` - ) - - const userFeedback = { - event_id: eventId, - name: user ? user.full_name : 'Anonymous', - email: user ? user.email : 'Anonymous', - comments: feedbackMessage, - } - Sentry.captureUserFeedback(userFeedback) - setIsSubmitting(false) - setView('success') - } - - const handleFeedbackMessage = (event: React.ChangeEvent) => { - setFeedbackMessage(event.target.value) - } - - if (view == 'feedbackForm') { - return ( - - - - Feedback message - - Please provide learning elements, separated by comma (,) - - - -