diff --git a/ganesh/.env.example b/ganesh/.env.example index ab063cb..09b8db6 100644 --- a/ganesh/.env.example +++ b/ganesh/.env.example @@ -6,7 +6,7 @@ POSTGRES_PASSWORD="postgres" POSTGRES_DB="postgres" # AUTH -NEXTAUTH_SECRET="secret" +AUTH_SECRET="secret" # DEEPL DEEPL_API_KEY="secret" diff --git a/ganesh/Dockerfile b/ganesh/Dockerfile index 7a62f84..27098d1 100644 --- a/ganesh/Dockerfile +++ b/ganesh/Dockerfile @@ -26,6 +26,7 @@ WORKDIR /app # Copy only necessary files from the builder stage COPY --from=builder /app/.next ./.next +COPY --from=builder /app/next.config.mjs ./ COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/public ./public COPY --from=builder /app/package.json ./package.json diff --git a/ganesh/docker-compose.yaml b/ganesh/docker-compose.yaml index 3d59718..ddc3fcb 100644 --- a/ganesh/docker-compose.yaml +++ b/ganesh/docker-compose.yaml @@ -1,5 +1,3 @@ -version: "3.8" - services: app: build: . @@ -8,8 +6,9 @@ services: - "3000:3000" environment: DATABASE_URL: ${DATABASE_URL_PRODUCTION} - NEXTAUTH_SECRET: ${NEXTAUTH_SECRET} NODE_ENV: production + AUTH_SECRET: ${AUTH_SECRET} + AUTH_URL: http://localhost:3000/ depends_on: - postgres networks: diff --git a/ganesh/next.config.mjs b/ganesh/next.config.mjs index 49a0dcd..d5a2172 100644 --- a/ganesh/next.config.mjs +++ b/ganesh/next.config.mjs @@ -5,12 +5,24 @@ const nextConfig = { images: { remotePatterns: [ { + protocol: 'https', hostname: 'avatars.githubusercontent.com', + port: '', + pathname: '**' }, { + protocol: 'https', hostname: 'github.com', + port: '', + pathname: '**' + }, + { + protocol: 'https', + hostname: 'raw.githubusercontent.com', + port: '', + pathname: '**' } - ] + ], } }; diff --git a/ganesh/src/app/[locale]/about/page.tsx b/ganesh/src/app/[locale]/about/page.tsx index 43dd59d..e0b8044 100644 --- a/ganesh/src/app/[locale]/about/page.tsx +++ b/ganesh/src/app/[locale]/about/page.tsx @@ -45,7 +45,14 @@ export default function AboutPage() {
{t("ctf_title")} - CTF.br Website Logo + CTF.br Website Logo
diff --git a/ganesh/src/app/[locale]/admin/dashboard/authors/page.tsx b/ganesh/src/app/[locale]/admin/dashboard/authors/page.tsx index 2f707ca..6ca6c20 100644 --- a/ganesh/src/app/[locale]/admin/dashboard/authors/page.tsx +++ b/ganesh/src/app/[locale]/admin/dashboard/authors/page.tsx @@ -1,6 +1,6 @@ import Pagination from '@/components/admin/pagination'; import Table from '@/components/admin/authors/table'; -import { Suspense, use } from 'react'; +import { Suspense } from 'react'; import { fetchAuthorsPages } from '@/services/data'; import type { Metadata } from 'next'; diff --git a/ganesh/src/app/[locale]/content/activity/[id]/page.tsx b/ganesh/src/app/[locale]/content/activity/[id]/page.tsx index dd32a2a..b0f724a 100644 --- a/ganesh/src/app/[locale]/content/activity/[id]/page.tsx +++ b/ganesh/src/app/[locale]/content/activity/[id]/page.tsx @@ -2,7 +2,6 @@ import { fetchPostById } from '@/services/data'; import { notFound } from 'next/navigation'; import type { Metadata } from 'next'; -import Terminal from '@/components/cards/terminal'; import Preview from '@/components/preview/preview'; import Container from '@/components/container'; export const metadata: Metadata = { diff --git a/ganesh/src/app/[locale]/content/article/[id]/page.tsx b/ganesh/src/app/[locale]/content/article/[id]/page.tsx index dd32a2a..b0f724a 100644 --- a/ganesh/src/app/[locale]/content/article/[id]/page.tsx +++ b/ganesh/src/app/[locale]/content/article/[id]/page.tsx @@ -2,7 +2,6 @@ import { fetchPostById } from '@/services/data'; import { notFound } from 'next/navigation'; import type { Metadata } from 'next'; -import Terminal from '@/components/cards/terminal'; import Preview from '@/components/preview/preview'; import Container from '@/components/container'; export const metadata: Metadata = { diff --git a/ganesh/src/app/[locale]/content/article/page.tsx b/ganesh/src/app/[locale]/content/article/page.tsx index 9d7f605..b076e72 100644 --- a/ganesh/src/app/[locale]/content/article/page.tsx +++ b/ganesh/src/app/[locale]/content/article/page.tsx @@ -1,5 +1,5 @@ import { fetchPosts, fetchPostsPages } from "@/services/data"; -import { Post, postTypes } from "@/models/post"; +import { Post } from "@/models/post"; import ClientArticlesComponent from "@/components/client/articles"; interface PageProps { diff --git a/ganesh/src/app/[locale]/content/page.tsx b/ganesh/src/app/[locale]/content/page.tsx index ee5a952..f8ce940 100644 --- a/ganesh/src/app/[locale]/content/page.tsx +++ b/ganesh/src/app/[locale]/content/page.tsx @@ -8,7 +8,6 @@ interface ContentPageProps { } export default async function ContentPage({ - searchParams }: ContentPageProps) { const [activities, articles, tips, videos]: [Post[], Post[], Post[], Video[]] = await Promise.all([ diff --git a/ganesh/src/app/[locale]/content/tip/[id]/page.tsx b/ganesh/src/app/[locale]/content/tip/[id]/page.tsx index dd32a2a..b0f724a 100644 --- a/ganesh/src/app/[locale]/content/tip/[id]/page.tsx +++ b/ganesh/src/app/[locale]/content/tip/[id]/page.tsx @@ -2,7 +2,6 @@ import { fetchPostById } from '@/services/data'; import { notFound } from 'next/navigation'; import type { Metadata } from 'next'; -import Terminal from '@/components/cards/terminal'; import Preview from '@/components/preview/preview'; import Container from '@/components/container'; export const metadata: Metadata = { diff --git a/ganesh/src/app/[locale]/layout.tsx b/ganesh/src/app/[locale]/layout.tsx index aeed75e..6adb868 100644 --- a/ganesh/src/app/[locale]/layout.tsx +++ b/ganesh/src/app/[locale]/layout.tsx @@ -26,7 +26,7 @@ export default async function RootLayout({ }) { const { locale } = await params; - if (!routing.locales.includes(locale as any)) { + if (!routing.locales.includes(locale as 'br' | 'en')) { notFound(); } diff --git a/ganesh/src/app/[locale]/news/[id]/page.tsx b/ganesh/src/app/[locale]/news/[id]/page.tsx index dd32a2a..b0f724a 100644 --- a/ganesh/src/app/[locale]/news/[id]/page.tsx +++ b/ganesh/src/app/[locale]/news/[id]/page.tsx @@ -2,7 +2,6 @@ import { fetchPostById } from '@/services/data'; import { notFound } from 'next/navigation'; import type { Metadata } from 'next'; -import Terminal from '@/components/cards/terminal'; import Preview from '@/components/preview/preview'; import Container from '@/components/container'; export const metadata: Metadata = { diff --git a/ganesh/src/app/[locale]/page.tsx b/ganesh/src/app/[locale]/page.tsx index 65a2bbc..a2d9655 100644 --- a/ganesh/src/app/[locale]/page.tsx +++ b/ganesh/src/app/[locale]/page.tsx @@ -1,9 +1,6 @@ -import EncryptButton from "@/components/button/encrypt-button"; -import Terminal from "@/components/cards/terminal"; import ClientHomeComponent from "@/components/client/home"; import { Sponsor } from "@/models/sponsor"; import { fetchSponsors } from "@/services/data"; -import Image from "next/image"; export default async function Page() { const sponsors: Sponsor[] = await fetchSponsors(); diff --git a/ganesh/src/auth.config.ts b/ganesh/src/auth.config.ts index 02b7525..a9a429a 100644 --- a/ganesh/src/auth.config.ts +++ b/ganesh/src/auth.config.ts @@ -1,4 +1,3 @@ -import { PrismaAdapter } from '@auth/prisma-adapter'; import type { NextAuthConfig } from 'next-auth'; import { prisma } from '@/services/prisma'; diff --git a/ganesh/src/components/admin/posts/edit-form.tsx b/ganesh/src/components/admin/posts/edit-form.tsx index 918367f..ac010a8 100644 --- a/ganesh/src/components/admin/posts/edit-form.tsx +++ b/ganesh/src/components/admin/posts/edit-form.tsx @@ -17,7 +17,7 @@ import { useActionState } from '@/lib/utils'; import { PostForm, PostTxtContent, postTypes } from '@/models/post'; import { State, updatePost } from '@/services/post'; import { Author } from '@/models/author'; -import { Suspense, useState } from 'react'; +import { useState } from 'react'; import Preview from '@/components/preview/preview'; import { Tabs, TabsContent, TabsList, TabsTrigger } from './tabs'; import TxtInput from './txt-input'; diff --git a/ganesh/src/components/admin/posts/txt-input.tsx b/ganesh/src/components/admin/posts/txt-input.tsx index 7ba84d5..f4af227 100644 --- a/ganesh/src/components/admin/posts/txt-input.tsx +++ b/ganesh/src/components/admin/posts/txt-input.tsx @@ -1,5 +1,3 @@ -import { State } from "@/services/post"; - export default function TxtInput({ label, name, diff --git a/ganesh/src/components/admin/sponsors/card.tsx b/ganesh/src/components/admin/sponsors/card.tsx index d14ddb6..ce939a0 100644 --- a/ganesh/src/components/admin/sponsors/card.tsx +++ b/ganesh/src/components/admin/sponsors/card.tsx @@ -1,11 +1,18 @@ import { Sponsor } from "@/models/sponsor"; import { DeleteSponsor, UpdateSponsor } from "./buttons"; +import Image from "next/image"; export default function Card({ id, name, logo, link, description, description_en }: Sponsor) { return ( <>
- {name} + {name} { const [isModalOpen, setIsModalOpen] = useState(false); diff --git a/ganesh/src/components/button/encrypt-button.tsx b/ganesh/src/components/button/encrypt-button.tsx index 8e59538..085056f 100644 --- a/ganesh/src/components/button/encrypt-button.tsx +++ b/ganesh/src/components/button/encrypt-button.tsx @@ -1,8 +1,6 @@ "use client"; import { useRef, useState } from "react"; -import { LockClosedIcon } from "@heroicons/react/24/outline"; -import { InformationCircleIcon } from "@heroicons/react/16/solid"; import { MagnifyingGlassIcon } from "@heroicons/react/16/solid"; import { motion } from "framer-motion"; import Link from "next/link"; @@ -16,7 +14,7 @@ interface EncryptButtonProps { targetText: string; } -export default function EncryptButton({ onClick, targetText }: EncryptButtonProps) { +export default function EncryptButton({ targetText }: EncryptButtonProps) { const intervalRef = useRef(null); const [text, setText] = useState(targetText); diff --git a/ganesh/src/components/cards/news.tsx b/ganesh/src/components/cards/news.tsx index bbce0b3..eac2bd7 100644 --- a/ganesh/src/components/cards/news.tsx +++ b/ganesh/src/components/cards/news.tsx @@ -1,5 +1,4 @@ import Image from "next/image"; -import Terminal from "./terminal"; import Link from "next/link"; import { ArrowRightCircleIcon } from "@heroicons/react/24/outline"; import { useLocale } from "next-intl"; diff --git a/ganesh/src/components/cards/terminal.tsx b/ganesh/src/components/cards/terminal.tsx index aedec39..68c015c 100644 --- a/ganesh/src/components/cards/terminal.tsx +++ b/ganesh/src/components/cards/terminal.tsx @@ -1,4 +1,4 @@ -import React, { ReactNode } from 'react'; +import React from 'react'; export default function Terminal({ children }: diff --git a/ganesh/src/components/client/contents.tsx b/ganesh/src/components/client/contents.tsx index e29700d..230725e 100644 --- a/ganesh/src/components/client/contents.tsx +++ b/ganesh/src/components/client/contents.tsx @@ -1,22 +1,22 @@ "use client"; import { Post } from "@/models/post"; -import { useLocale, useTranslations } from "next-intl"; +import { useTranslations } from "next-intl"; import Container from "../container"; import Link from "next/link"; import { ArrowRightCircleIcon } from "@heroicons/react/24/outline"; import Slider from "../slider/slider"; +import { Video } from "@/models/video"; interface ContentsProps { activities: Post[]; articles: Post[]; tips: Post[]; - videos: any; + videos: Video[]; } export default function Contents({ activities, articles, tips }: ContentsProps) { const t = useTranslations('Navbar'); - const locale = useLocale(); return (
diff --git a/ganesh/src/components/client/home.tsx b/ganesh/src/components/client/home.tsx index 34549ed..8e516c7 100644 --- a/ganesh/src/components/client/home.tsx +++ b/ganesh/src/components/client/home.tsx @@ -47,7 +47,13 @@ export default function ClientHomeComponent({ sponsors }: HomeProps) {
{sponsors.map((sponsor) => (
- {sponsor.name} + {sponsor.name}

{sponsor.description}

))} diff --git a/ganesh/src/components/matrix.tsx b/ganesh/src/components/matrix.tsx index 51014a0..1303bf3 100644 --- a/ganesh/src/components/matrix.tsx +++ b/ganesh/src/components/matrix.tsx @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + 'use client'; import React from "react"; @@ -6,10 +8,10 @@ import { useEffect } from "react"; import clsx from "clsx"; const renderMatrix = (ref: React.RefObject, color: string | undefined) => { - let canvas = ref.current; + const canvas = ref.current; if (!canvas) return; - let context = canvas.getContext("2d"); + const context = canvas.getContext("2d"); if (!context) return; diff --git a/ganesh/src/components/navbar.tsx b/ganesh/src/components/navbar.tsx index 15d07ee..071cec5 100644 --- a/ganesh/src/components/navbar.tsx +++ b/ganesh/src/components/navbar.tsx @@ -1,7 +1,7 @@ "use client"; import Link from "next/link"; -import { usePathname, useRouter } from 'next/navigation'; +import { usePathname } from 'next/navigation'; import Image from 'next/image'; import clsx from 'clsx'; import { useState } from "react"; @@ -54,12 +54,6 @@ export default function Navbar() { const t = useTranslations('Navbar'); const locale = useLocale(); - const router = useRouter(); - const changeLanguage = (lang: string) => { - // This will navigate to the new locale while preserving the current path. - router.push(`/${lang}${pathname}`); - }; - return ( <> {!pathname.includes("/admin") && ( diff --git a/ganesh/src/i18n/request.ts b/ganesh/src/i18n/request.ts index 5aaece6..287a78e 100644 --- a/ganesh/src/i18n/request.ts +++ b/ganesh/src/i18n/request.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import { getRequestConfig } from 'next-intl/server'; import { routing } from './routing'; diff --git a/ganesh/src/i18n/routing.ts b/ganesh/src/i18n/routing.ts index 9592c06..ec3e77f 100644 --- a/ganesh/src/i18n/routing.ts +++ b/ganesh/src/i18n/routing.ts @@ -1,5 +1,4 @@ import { defineRouting } from 'next-intl/routing'; -import { createNavigation } from 'next-intl/navigation'; export const routing = defineRouting({ // A list of all locales that are supported diff --git a/ganesh/src/middleware.ts b/ganesh/src/middleware.ts index db6a863..abbb895 100644 --- a/ganesh/src/middleware.ts +++ b/ganesh/src/middleware.ts @@ -1,8 +1,10 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import NextAuth from 'next-auth'; import { authConfig } from '@/auth.config'; import createIntlMiddleware from 'next-intl/middleware'; import { routing } from './i18n/routing'; -import { NextRequest, NextResponse } from 'next/server'; +import { NextResponse } from 'next/server'; // Create middleware functions for each feature. const { auth } = NextAuth(authConfig) @@ -35,7 +37,7 @@ export default auth(async function middleware(request: any) { export const config = { matcher: [ // For auth: ignore api routes, Next.js internals and static assets - '/((?!api|_next/static|_next/image|favicon.ico|.*\\.png$).*)', + '/((?!api|_next/static|_next/image|.*\\.png$).*)', // For internationalized paths '/', '/(en|br)/:path*', diff --git a/ganesh/src/services/auth.ts b/ganesh/src/services/auth.ts index 6c3fc30..d162a72 100644 --- a/ganesh/src/services/auth.ts +++ b/ganesh/src/services/auth.ts @@ -13,6 +13,7 @@ export async function authenticate( email: formData.get('email') as string, password: formData.get('password') as string, redirectTo: '/br/admin/dashboard', + callbackUrl: '/br/admin/dashboard' }); } catch (error) { if (error instanceof AuthError) { diff --git a/ganesh/src/services/data.ts b/ganesh/src/services/data.ts index 60afd16..15a1253 100644 --- a/ganesh/src/services/data.ts +++ b/ganesh/src/services/data.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import { prisma } from '@/services/prisma'; import { Post, PostForm } from '@/models/post'; import { Author } from '@/models/author'; @@ -25,7 +27,7 @@ export const fetchAuthors = async (): Promise => { try { const data = await prisma.author.findMany({}); - const authors: Author[] = data.map((author) => ({ + const authors: Author[] = data.map((author: any) => ({ id: author.id, github: author.github, name: author.name ?? undefined, @@ -49,7 +51,7 @@ export const fetchAuthorsByPage = async (page: number): Promise => { } }); - const authors: Author[] = data.map((author) => ({ + const authors: Author[] = data.map((author: any) => ({ id: author.id, github: author.github, name: author.name ?? undefined, @@ -139,7 +141,7 @@ export const fetchPosts = async (page: number, type?: PostForm['type'], publishe return []; } - const posts: Post[] = data.map((post) => ({ + const posts: Post[] = data.map((post: any) => ({ id: post.id, title: post.title, title_en: post.title_en ?? undefined, @@ -221,7 +223,7 @@ export const fetchSponsors = async (): Promise => { }, }); - const sponsors: Sponsor[] = data.map((sponsor) => ({ + const sponsors: Sponsor[] = data.map((sponsor: any) => ({ id: sponsor.id, name: sponsor.name, logo: sponsor.logo, @@ -247,7 +249,7 @@ export const fetchVideos = async (): Promise => { }, }); - const videos: Video[] = data.map((video) => ({ + const videos: Video[] = data.map((video: any) => ({ id: video.id, title: video.title, title_en: video.title_en, diff --git a/ganesh/src/services/prisma.ts b/ganesh/src/services/prisma.ts index 55acf8d..e3ab639 100644 --- a/ganesh/src/services/prisma.ts +++ b/ganesh/src/services/prisma.ts @@ -1,9 +1,13 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import { PrismaClient } from "@prisma/client"; declare global { - var prisma: PrismaClient | undefined; + let prisma: PrismaClient | undefined; } -export const prisma = global.prisma || new PrismaClient(); +export const prisma = (global as any).prisma ?? new PrismaClient(); -if (process.env.NODE_ENV !== "production") global.prisma = prisma; +if (process.env.NODE_ENV !== "production") { + (global as any).prisma = prisma; +}