# Paste

id: vwxmq49
createdBy: 281113457833672706
content:
  "use client";

  import { useSession } from "next-auth/react";
  import { useRouter } from "next/navigation";
  import { useCallback, useEffect, useState } from "react";
  import Editor from "./paste-form/Editor";
  import SidebarPanel from "./paste-form/SidebarPanel";
  import AuthSection from "./paste-form/AuthSection";

  export default function PasteForm() {
    const router = useRouter();
    const { data: session } = useSession();

    const [title, setTitle] = useState("");
    const [content, setContent] = useState("");
    const [password, setPassword] = useState("");
    const [maxViews, setMaxViews] = useState("");
    const [isSaving, setIsSaving] = useState(false);
    const [advanced, setAdvanced] = useState(true);

    const handleSave = useCallback(async () => {
      if (!content.trim()) return;
      setIsSaving(true);

      const res = await fetch("/api/paste", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          title: title.trim() || null,
          content,
          password: password || null,
          maxViews: maxViews ? parseInt(maxViews, 10) : null,
          createdBy: session?.user?.id || null,
        }),
      });

      if (res.ok) {
        const data = await res.json();
        router.push(`/${data.id}`);
      }

      setIsSaving(false);
    }, [title, content, password, maxViews, session, router]);

    // Raccourci clavier Ctrl+S
    useEffect(() => {
      const onKeyDown = (e: KeyboardEvent) => {
        if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "s") {
          e.preventDefault();
          if (!isSaving && content.trim()) handleSave();
        }
      };
      window.addEventListener("keydown", onKeyDown);
      return () => window.removeEventListener("keydown", onKeyDown);
    }, [handleSave, isSaving, content]);

    return (
      <div className="w-screen h-screen bg-[#0e0f13] text-white relative">
        <Editor content={content} setContent={setContent} />
        <SidebarPanel
          title={title}
          setTitle={setTitle}
          maxViews={maxViews}
          setMaxViews={setMaxViews}
          password={password}
          setPassword={setPassword}
          content={content}
          isSaving={isSaving}
          handleSave={handleSave}
          advanced={advanced}
          setAdvanced={setAdvanced}
        />
        <AuthSection />
      </div>
    );
  }


id: qa65aao
createdBy: 281113457833672706
content:
  'use client';
  import { Eye, Lock, Settings } from 'lucide-react';
  import { useState } from 'react';

  export default function PasteOptionsPanel({
    password,
    setPassword,
    maxViews,
    setMaxViews,
    onCreate,
    disabled,
  }: {
    password: string;
    setPassword: (val: string) => void;
    maxViews: string;
    setMaxViews: (val: string) => void;
    onCreate: () => void;
    disabled: boolean;
  }) {
    const [open, setOpen] = useState(true);

    return (
      <aside className="w-80 rounded-2xl border border-[#1b1d2a] bg-[#0f111a]/60 shadow-xl p-5 flex flex-col justify-between text-sm backdrop-blur-md">
        <div>
          <div className="flex justify-between items-center mb-6">
            <h2 className="text-lg font-bold text-white">Alt<span className="text-blue-400">Bin</span></h2>
            <button
              className="bg-green-600 hover:bg-green-500 text-xs font-semibold px-3 py-1 rounded-full"
              onClick={onCreate}
              disabled={disabled}
            >
              + CREATE
            </button>
          </div>

          <button
            className="flex items-center gap-2 text-neutral-400 text-xs mb-3"
            onClick={() => setOpen(!open)}
          >
            <Settings size={14} />
            Advanced {open ? '▾' : '▸'}
          </button>

          {open && (
            <div className="space-y-6">
              <div className="space-y-2">
                <label className="flex items-center gap-2 text-neutral-400 text-xs uppercase tracking-wide">
                  <Eye size={14} /> Max Views
                </label>
                <input
                  type="number"
                  value={maxViews}
                  onChange={e => setMaxViews(e.target.value)}
                  placeholder="∞"
                  className="w-full bg-[#1a1d29] text-white p-2 rounded outline-none"
                />
                <p className="text-[11px] text-neutral-500">Delete after X views</p>
              </div>

              <div className="space-y-2">
                <label className="flex items-center gap-2 text-neutral-400 text-xs uppercase tracking-wide">
                  <Lock size={14} /> Password
                </label>
                <input
                  type="password"
                  value={password}
                  onChange={e => setPassword(e.target.value)}
                  placeholder="Optional password"
                  className="w-full bg-[#1a1d29] text-white p-2 rounded outline-none"
                />
                <p className="text-[11px] text-neutral-500">Require password to view</p>
              </div>
            </div>
          )}
        </div>

        <button
          disabled={disabled}
          onClick={onCreate}
          className={`mt-8 py-2 rounded-md text-sm tracking-wide font-medium flex items-center justify-center ${
            disabled
              ? 'bg-[#1a1d29] text-neutral-500 opacity-50 cursor-not-allowed'
              : 'bg-[#1a1d29] text-white hover:bg-neutral-800'
          }`}
        >
          <span className="text-lg">🔒</span> SAVE PASTE
        </button>
      </aside>
    );
  }


id: yfuxu6a
createdBy: 281113457833672706
content:
  import { prisma } from '@/lib/prisma';
  import bcrypt from 'bcryptjs';
  import { NextRequest, NextResponse } from 'next/server';

  export const dynamic = 'force-dynamic';
  export const revalidate = 0;

  export async function POST(
    request: NextRequest,
    context: { params: Promise<{ id: string }> } // 👈 params est une Promise
  ) {
    const { id: pasteId } = await context.params; // 👈 on attend params

    const { password = '' } = await request.json();

    if (!pasteId) {
      return NextResponse.json({ error: 'Invalid ID' }, { status: 400 });
    }

    const paste = await prisma.paste.findUnique({ where: { id: pasteId } });
    if (!paste) {
      return NextResponse.json({ error: 'Not found' }, { status: 404 });
    }

    if (paste.maxViews !== null && paste.views >= paste.maxViews) {
      await prisma.paste.delete({ where: { id: paste.id } });
      return NextResponse.json({ error: 'Max views exceeded' }, { status: 404 });
    }

    if (paste.password) {
      const valid = await bcrypt.compare(password, paste.password);
      if (!valid) {
        return NextResponse.json({ error: 'Invalid password' }, { status: 403 });
      }
    }

    const updated = await prisma.paste.update({
      where: { id: paste.id },
      data: { views: { increment: 1 } },
      select: {
        id: true,
        title: true,
        content: true,
        createdAt: true,
        views: true,
        maxViews: true,
        password: true,
      },
    });

    const payload = {
      id: updated.id,
      title: updated.title,
      content: updated.content,
      createdAt: updated.createdAt,
      views: updated.views,
      protected: !!updated.password,
    };

    if (updated.maxViews !== null && updated.views >= updated.maxViews) {
      prisma.paste.delete({ where: { id: updated.id } }).catch(() => {});
    }

    return NextResponse.json(payload, {
      headers: { 'Cache-Control': 'no-store' },
    });
  }


id: 5p95uya
createdBy: 281113457833672706
content:
  'use client';

  import {
    CalendarDays,
    Copy,
    Download,
    Eye,
    FileText,
    Plus,
  } from 'lucide-react';
  import { useRouter } from 'next/navigation';
  import { use, useEffect, useRef, useState } from 'react'; // 👈 import de `use`

  import Prism from 'prismjs';
  import 'prismjs/components/prism-bash';
  import 'prismjs/components/prism-javascript';
  import 'prismjs/components/prism-json';
  import 'prismjs/components/prism-python';
  import 'prismjs/components/prism-typescript';
  import 'prismjs/themes/prism-tomorrow.css';

  import 'prismjs/plugins/line-numbers/prism-line-numbers.css';
  import 'prismjs/plugins/line-numbers/prism-line-numbers.js';

  /** ---------- Loader animé (spinner + skeletons) ---------- */
  function LoadingPaste() {
    return (
      <div className="relative w-screen h-screen bg-[#0e0f13] text-white flex overflow-hidden">
        {/* Zone code (skeleton lignes) */}
        <div className="flex-1 h-full font-mono text-sm">
          <div className="h-full overflow-auto pt-6 pb-6 px-6">
            <div className="mb-4 flex items-center gap-2">
              <div
                className="h-5 w-5 rounded-full border-2 border-white/30 border-t-transparent animate-spin"
                aria-hidden
              />
              <span className="text-white/70 text-sm">Chargement du paste…</span>
            </div>
            <div className="space-y-2">
              {Array.from({ length: 28 }).map((_, i) => (
                <div
                  key={i}
                  className={`h-3 rounded bg-white/10 animate-pulse ${i % 3 === 0 ? 'w-5/6' : i % 3 === 1 ? 'w-11/12' : 'w-3/4'}`}
                />
              ))}
            </div>
          </div>
        </div>

        {/* Sidebar (skeleton cartes + boutons) */}
        <div
          className="
            absolute top-4 right-4 w-[300px] rounded-2xl p-5 text-sm
            backdrop-blur-xl shadow-2xl
            bg-[linear-gradient(to_bottom_right,#1a2035,#101522)]
            ring-1 ring-white/10 mr-4
          "
        >
          <div className="mb-4">
            <div className="flex items-center justify-between">
              <div className="h-6 w-24 bg-white/10 rounded animate-pulse" />
              <div className="h-7 w-20 rounded-full bg-green-600/60 animate-pulse" />
            </div>
            <div className="h-4 w-40 bg-white/10 rounded mt-2 animate-pulse" />
          </div>

          <div className="grid grid-cols-2 gap-3 text-neutral-300">
            <div className="flex items-center gap-2 rounded-lg px-3 py-2 bg-[#151b2e] ring-1 ring-white/15">
              <div className="h-4 w-4 rounded bg-white/10 animate-pulse" />
              <div className="flex-1 space-y-1">
                <div className="h-3 w-10 bg-white/10 rounded animate-pulse" />
                <div className="h-3 w-12 bg-white/20 rounded animate-pulse" />
              </div>
            </div>
            <div className="flex items-center gap-2 rounded-lg px-3 py-2 bg-[#151b2e] ring-1 ring-white/15">
              <div className="h-4 w-4 rounded bg-white/10 animate-pulse" />
              <div className="flex-1 space-y-1">
                <div className="h-3 w-12 bg-white/10 rounded animate-pulse" />
                <div className="h-3 w-16 bg-white/20 rounded animate-pulse" />
              </div>
            </div>
          </div>

          <div className="h-px bg-white/10 my-4" />

          <div className="grid grid-cols-4 gap-2">
            {Array.from({ length: 4 }).map((_, i) => (
              <div key={i} className="h-9 rounded-lg bg-[#151b2e] ring-1 ring-white/10 animate-pulse" />
            ))}
          </div>

          <div className="mt-3 h-3 w-16 mx-auto bg-green-400/50 rounded animate-pulse" />
        </div>
      </div>
    );
  }
  /** -------------------------------------------------------- */

  export default function PastePage({
    params,
  }: {
    params: Promise<{ id: string }>; // 👈 params est une Promise
  }) {
    const { id } = use(params); // 👈 on “unwrap” la Promise côté client

    const [paste, setPaste] = useState<any | null>(null);
    const [error, setError] = useState('');
    const [loading, setLoading] = useState(true);
    const [language, setLanguage] = useState<string>('language-javascript');
    const [copied, setCopied] = useState(false);

    const codeRef = useRef<HTMLPreElement | null>(null);
    const router = useRouter();

    const fetchPaste = async (pwd?: string) => {
      setLoading(true);
      const res = await fetch(`/api/paste/${id}`, { // 👈 utilise `id`
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ password: pwd || '' }),
      });

      if (res.status === 403) {
        setError('Invalid password.');
        setLoading(false);
        return;
      }
      if (res.status === 404) {
        setError('Paste not found or expired.');
        setLoading(false);
        return;
      }

      const data = await res.json();
      setPaste(data);

      if (data.content.includes('function') || data.content.includes('const')) {
        setLanguage('language-javascript');
      } else if (data.content.includes('import') || data.content.includes('export')) {
        setLanguage('language-typescript');
      } else if (data.content.includes('{') && data.content.includes('}')) {
        setLanguage('language-json');
      } else {
        setLanguage('language-bash');
      }

      setLoading(false);
    };

    useEffect(() => {
      fetchPaste();
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [id]); // 👈 dépend de `id`

    useEffect(() => {
      if (paste?.content) {
        Prism.highlightAll();
      }
    }, [paste]);

    if (loading) return <LoadingPaste />;

    if (error || (paste?.protected && !paste?.content)) {
      return (
        <div className="h-screen w-screen bg-[#0e0f13] flex items-center justify-center text-white">
          <form
            onSubmit={(e) => {
              e.preventDefault();
              fetchPaste((e.currentTarget as any).password.value);
            }}
            className="
              w-full max-w-sm rounded-2xl p-6 space-y-4
              backdrop-blur-xl shadow-2xl
              bg-[linear-gradient(to_bottom_right,rgba(20,24,38,0.9),rgba(14,16,24,0.9))]
              ring-1 ring-white/10
            "
          >
            <h2 className="text-xl font-bold">
              <span className="text-red-400">🔒 Protected Paste</span>
            </h2>
            {error && <p className="text-red-500 text-sm">{error}</p>}

            <input
              name="password"
              type="password"
              placeholder="Enter password"
              className="
                w-full rounded-xl bg-[#0f1320]/60 text-white placeholder:text-neutral-500
                px-3 py-2 outline-none
                ring-1 ring-white/10 focus:ring-2 focus:ring-blue-500/50
              "
            />

            <button
              type="submit"
              className="
                w-full inline-flex items-center justify-center gap-2 rounded-xl py-2 text-sm font-medium
                bg-gradient-to-b from-[#1b2135] to-[#141a2a] text-white ring-1 ring-white/10
                hover:from-[#232a41] hover:to-[#161d2f]
                focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-400/60
              "
            >
              View Paste
            </button>
          </form>
        </div>
      );
    }

    return (
      <div className="relative w-screen h-screen bg-[#0e0f13] text-white flex overflow-hidden">
        <div className="flex-1 h-full font-mono text-sm">
          <pre
            ref={codeRef}
            className="h-full overflow-auto pt-6 pb-6 px-6 line-numbers"
          >
            <code className={`${language} whitespace-pre-wrap break-words`}>
              {paste.content}
            </code>
          </pre>
        </div>

        <div
          className="
            absolute top-4 right-4 w-[300px] rounded-2xl p-5 text-sm
            backdrop-blur-xl shadow-2xl
            bg-[linear-gradient(to_bottom_right,#1a2035,#101522)]
            ring-1 ring-white/10 mr-4
          "
        >
          <div className="mb-4">
            <div className="flex items-center justify-between">
              <h2 className="text-lg font-bold tracking-tight">
                Alt<span className="text-blue-400">Bin</span>
              </h2>
              <button
                onClick={() => router.push('/')}
                className="
                  cursor-pointer inline-flex items-center gap-1 rounded-full px-3 py-1 text-xs font-semibold
                  bg-green-600 text-white shadow-sm
                  hover:bg-green-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-green-400/60
                "
              >
                <Plus size={14} />
                CREATE
              </button>
            </div>
            {paste.title && (
              <h1
                className="text-sm font-semibold text-blue-300 truncate mt-1"
                title={paste.title}
              >
                {paste.title}
              </h1>
            )}
          </div>

          <div className="grid grid-cols-2 gap-3 text-neutral-300">
            <div className="flex items-center gap-2 rounded-lg px-3 py-2 bg-[#151b2e] ring-1 ring-white/15">
              <Eye size={16} />
              <div className="leading-tight">
                <div className="text-xs text-neutral-400">Views</div>
                <div className="text-sm font-medium text-white">{paste.views}</div>
              </div>
            </div>
            <div className="flex items-center gap-2 rounded-lg px-3 py-2 bg-[#151b2e] ring-1 ring-white/15">
              <CalendarDays size={16} />
              <div className="leading-tight">
                <div className="text-xs text-neutral-400">Created</div>
                <div className="text-sm font-medium text-white">
                  {new Date(paste.createdAt).toLocaleDateString()}
                </div>
              </div>
            </div>
          </div>

          <div className="h-px bg-white/10 my-4" />

          <div className="grid grid-cols-4 gap-2">
            <button
              onClick={async () => {
                await navigator.clipboard.writeText(paste.content);
                setCopied(true);
                setTimeout(() => setCopied(false), 1200);
              }}
              className="cursor-pointer inline-flex items-center justify-center rounded-lg p-2 bg-[#151b2e] ring-1 ring-white/10 hover:bg-[#1e253d] hover:ring-blue-400/30"
              title="Copy"
            >
              <Copy size={18} />
            </button>

            <button
              onClick={() => window.open(`/api/${id}?raw=1`, '_blank')} // 👈 utilise `id`
              className="cursor-pointer inline-flex items-center justify-center rounded-lg p-2 bg-[#151b2e] ring-1 ring-white/10 hover:bg-[#1e253d] hover:ring-blue-400/30"
              title="Raw"
            >
              <FileText size={18} />
            </button>

            <button
              onClick={() => {
                const blob = new Blob([paste.content], { type: 'text/plain' });
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = `${id}.txt`; // 👈 utilise `id`
                a.click();
                URL.revokeObjectURL(url);
              }}
              className="cursor-pointer inline-flex items-center justify-center rounded-lg p-2 bg-[#151b2e] ring-1 ring-white/10 hover:bg-[#1e253d] hover:ring-blue-400/30"
              title="Download"
            >
              <Download size={18} />
            </button>

            <button
              onClick={() => router.push('/')}
              className="cursor-pointer inline-flex items-center justify-center rounded-lg p-2 bg-[#151b2e] ring-1 ring-white/10 hover:bg-[#1e253d] hover:ring-blue-400/30"
              title="New paste"
            >
              <Plus size={18} />
            </button>
          </div>

          <div
            className={`mt-3 text-center text-xs transition-opacity ${
              copied ? 'opacity-100 text-green-400' : 'opacity-0'
            }`}
          >
            Copied!
          </div>
        </div>
      </div>
    );
  }


id: hmj3ytp
createdBy: 281113457833672706
content:
  import { redirect } from "next/navigation";

  export default function RawIndexPage() {
    redirect("/");
  }


id: 68u38u6
createdBy: 281113457833672706
content:
  'use client';

  import { useRouter } from 'next/navigation';
  import Prism from 'prismjs';
  import { useEffect, useState } from 'react';

  import 'prismjs/components/prism-bash';
  import 'prismjs/components/prism-javascript';
  import 'prismjs/components/prism-json';
  import 'prismjs/components/prism-python';
  import 'prismjs/components/prism-typescript';
  import 'prismjs/plugins/line-numbers/prism-line-numbers.css';
  import 'prismjs/plugins/line-numbers/prism-line-numbers.js';
  import 'prismjs/themes/prism-tomorrow.css';

  import CodeViewer from '@/components/paste/CodeViewer';
  import LoadingPaste from '@/components/paste/LoadingPaste';
  import PasswordForm from '@/components/paste/PasswordForm';
  import PasteSidebar from '@/components/paste/PasteSidebar';

  export default function PastePage({ params }: { params: { id: string } }) {
    const { id } = params; // ✅ ici params est direct, pas besoin de use() ni Promise
    const router = useRouter();

    const [paste, setPaste] = useState<any | null>(null);
    const [error, setError] = useState('');
    const [loading, setLoading] = useState(true);
    const [language, setLanguage] = useState<string>('language-javascript');

    const fetchPaste = async (pwd?: string) => {
      setLoading(true);
      const res = await fetch(`/api/paste/${id}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ password: pwd || '' }),
      });

      if (res.status === 403) {
        setError('Invalid password.');
        setLoading(false);
        return;
      }
      if (res.status === 404) {
        setError('Paste not found or expired.');
        setLoading(false);
        return;
      }

      const data = await res.json();
      setPaste(data);

      if (data.content.includes('function') || data.content.includes('const')) {
        setLanguage('language-javascript');
      } else if (data.content.includes('import') || data.content.includes('export')) {
        setLanguage('language-typescript');
      } else if (data.content.includes('{') && data.content.includes('}')) {
        setLanguage('language-json');
      } else {
        setLanguage('language-bash');
      }

      setLoading(false);
    };

    useEffect(() => {
      fetchPaste();
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [id]);

    useEffect(() => {
      if (paste?.content) {
        Prism.highlightAll();
      }
    }, [paste]);

    if (loading) return <LoadingPaste />;

    if (error || (paste?.protected && !paste?.content)) {
      return <PasswordForm error={error} onSubmit={(pwd) => fetchPaste(pwd)} />;
    }

    return (
      <div className="relative w-screen h-screen bg-[#0e0f13] text-white flex overflow-hidden">
        <CodeViewer paste={paste} language={language} />
        <PasteSidebar paste={paste} id={id} />
      </div>
    );
  }


id: jy0sbcs
createdBy: 281113457833672706
content:
  generator client {
    provider = "prisma-client-js"
  }

  datasource db {
    provider = "sqlite"
    url      = "file:./altbin.db"
  }

  model Paste {
    id        String   @id @default(cuid())
    title     String?
    content   String
    password  String?
    maxViews  Int?
    views     Int      @default(0)
    size      Int?
    createdAt DateTime @default(now())
    createdBy String?

    dummyId String?
    dummy   Dummy?    @relation(fields: [dummyId], references: [id])
  }

  model Dummy {
    id     String  @id @default(cuid())
    pastes Paste[]
  }


id: 9itwyk4
createdBy: 281113457833672706
content:
  'use client';

  import { useRouter } from 'next/navigation';
  import Prism from 'prismjs';
  import { use, useEffect, useState } from 'react';

  // === Prism Languages Import ===
  import 'prismjs/components/prism-bash';
  import 'prismjs/components/prism-c';
  import 'prismjs/components/prism-cpp';
  import 'prismjs/components/prism-csharp';
  import 'prismjs/components/prism-css';
  import 'prismjs/components/prism-dart';
  import 'prismjs/components/prism-docker';
  import 'prismjs/components/prism-go';
  import 'prismjs/components/prism-java';
  import 'prismjs/components/prism-javascript';
  import 'prismjs/components/prism-json';
  import 'prismjs/components/prism-kotlin';
  import 'prismjs/components/prism-markdown';
  import 'prismjs/components/prism-php';
  import 'prismjs/components/prism-python';
  import 'prismjs/components/prism-ruby';
  import 'prismjs/components/prism-rust';
  import 'prismjs/components/prism-scala';
  import 'prismjs/components/prism-sql';
  import 'prismjs/components/prism-swift';
  import 'prismjs/components/prism-typescript';
  import 'prismjs/components/prism-yaml';

  // === Prism Plugins ===
  import 'prismjs/plugins/line-numbers/prism-line-numbers.css';
  import 'prismjs/plugins/line-numbers/prism-line-numbers.js';
  import 'prismjs/themes/prism-tomorrow.css';

  // === Components ===
  import AuthSection from "@/components/paste-form/AuthSection";
  import CodeViewer from '@/components/paste/CodeViewer';
  import LoadingPaste from '@/components/paste/LoadingPaste';
  import PasswordForm from '@/components/paste/PasswordForm';
  import PasteSidebar from '@/components/paste/PasteSidebar';

  export default function PastePage({
    params,
  }: {
    params: Promise<{ id: string }>;
  }) {
    const { id } = use(params);
    const router = useRouter();

    const [paste, setPaste] = useState<any | null>(null);
    const [error, setError] = useState('');
    const [loading, setLoading] = useState(true);
    const [language, setLanguage] = useState<string>('language-javascript');

    const fetchPaste = async (pwd?: string) => {
      setLoading(true);
      const res = await fetch(`/api/paste/${id}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ password: pwd || '' }),
      });

      if (res.status === 403) {
        setError('Invalid password.');
        setLoading(false);
        return;
      }
      if (res.status === 404) {
        setError('Paste not found or expired.');
        setLoading(false);
        return;
      }

      const data = await res.json();
      setPaste(data);

      // === Détection simple du langage ===
      const content = data.content || "";

      if (content.startsWith('<!DOCTYPE html') || content.startsWith('<html')) {
        setLanguage('language-markup'); // HTML/XML
      } else if (content.includes('import React') || content.includes('function') || content.includes('const')) {
        setLanguage('language-javascript');
      } else if (content.includes('export') || content.includes('interface')) {
        setLanguage('language-typescript');
      } else if (content.includes('class ') && content.includes('public static void main')) {
        setLanguage('language-java');
      } else if (content.includes('#include') && content.includes('printf')) {
        setLanguage('language-c');
      } else if (content.includes('std::') || content.includes('cout <<')) {
        setLanguage('language-cpp');
      } else if (content.includes('using System;')) {
        setLanguage('language-csharp');
      } else if (content.includes('<?php')) {
        setLanguage('language-php');
      } else if (content.includes('def ') || content.includes('print(')) {
        setLanguage('language-python');
      } else if (content.includes('fn main()') || content.includes('let mut')) {
        setLanguage('language-rust');
      } else if (content.includes('func main()') || content.includes('package main')) {
        setLanguage('language-go');
      } else if (content.includes('puts ') || content.includes('end')) {
        setLanguage('language-ruby');
      } else if (content.toLowerCase().includes('select ') || content.toLowerCase().includes('insert into')) {
        setLanguage('language-sql');
      } else if (content.startsWith('# ') || content.includes('```')) {
        setLanguage('language-markdown');
      } else if (content.includes(': ') && !content.includes(';') && content.includes('\n')) {
        setLanguage('language-yaml');
      } else if (content.includes('val ') || content.includes('object ')) {
        setLanguage('language-scala');
      } else if (content.includes('fun main()') && content.includes('val ')) {
        setLanguage('language-kotlin');
      } else if (content.includes('import Foundation') || content.includes('func ')) {
        setLanguage('language-swift');
      } else if (content.toLowerCase().includes('from ') && content.toLowerCase().includes('docker')) {
        setLanguage('language-docker');
      } else {
        setLanguage('language-bash'); // fallback
      }

      setLoading(false);
    };

    useEffect(() => {
      fetchPaste();
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [id]);

    useEffect(() => {
      if (paste?.content) {
        Prism.highlightAll();
      }
    }, [paste]);

    if (loading) return <LoadingPaste />;

    if (error || (paste?.protected && !paste?.content)) {
      return <PasswordForm error={error} onSubmit={(pwd) => fetchPaste(pwd)} />;
    }

    return (
      <div className="relative w-screen h-screen bg-[#0e0f13] text-white flex overflow-hidden">
        <CodeViewer paste={paste} language={language} />
        <PasteSidebar paste={paste} id={id} />
        <AuthSection />
      </div>
    );
  }


id: td9mgv7
createdBy: 281113457833672706
content:
  -- Création d'une table utilisateurs
  CREATE TABLE users (
      id SERIAL PRIMARY KEY,
      username VARCHAR(50) NOT NULL UNIQUE,
      email VARCHAR(100) NOT NULL,
      created_at TIMESTAMP DEFAULT NOW()
  );

  -- Insertion de données
  INSERT INTO users (username, email)
  VALUES 
  ('alice', 'alice@example.com'),
  ('bob', 'bob@example.com');

  -- Sélection de données
  SELECT id, username, email
  FROM users
  WHERE created_at > NOW() - INTERVAL '7 days'
  ORDER BY created_at DESC;

  -- Mise à jour d'un utilisateur
  UPDATE users
  SET email = 'alice.new@example.com'
  WHERE username = 'alice';

  -- Suppression
  DELETE FROM users
  WHERE username = 'bob';


id: qnikg1j
createdBy: 281113457833672706
content:
  +++++ +++++             initialize counter (cell #0) to 10
  [                       use loop to set 70/100/30 in cells #1–3
      > +++++ ++          add 7 to cell #1
      > +++++ +++++       add 10 to cell #2
      > +++               add 3 to cell #3
      <<< -                decrement counter (cell #0)
  ]
  > ++ .                  print 'H'
  > + .                   print 'e'
  +++++ ++ .              print 'l'
  .                       print 'l'
  +++ .                   print 'o'
  > ++ .                  print ' '
  << +++++ +++++ +++++ .  print 'W'
  > +++++ +++++ .         print 'o'
  +++ .                   print 'r'
  ----- - .               print 'l'
  ----- --- .             print 'd'
  > + .                   print '!'


id: 5rsf9su
createdBy: 281113457833672706
content:
  'use client';

  import { useRouter } from 'next/navigation';
  import Prism from 'prismjs';
  import { use, useEffect, useState } from 'react';

  import 'prismjs/plugins/line-numbers/prism-line-numbers.css';
  import 'prismjs/plugins/line-numbers/prism-line-numbers.js';
  import 'prismjs/themes/prism-tomorrow.css';

  import AuthSection from "@/components/paste-form/AuthSection";
  import CodeViewer from '@/components/paste/CodeViewer';
  import LoadingPaste from '@/components/paste/LoadingPaste';
  import PasswordForm from '@/components/paste/PasswordForm';
  import PasteSidebar from '@/components/paste/PasteSidebar';


  async function loadLanguage(lang: string) {
    try {
      await import(`prismjs/components/prism-${lang}.js`);
    } catch (err) {
      console.warn(`[Prism] Language '${lang}' introuvable. Fallback -> plaintext`);
    }
  }

  export default function PastePage({
    params,
  }: {
    params: Promise<{ id: string }>;
  }) {
    const { id } = use(params);
    const router = useRouter();

    const [paste, setPaste] = useState<any | null>(null);
    const [error, setError] = useState('');
    const [loading, setLoading] = useState(true);
    const [language, setLanguage] = useState<string>('language-javascript');

    const fetchPaste = async (pwd?: string) => {
      setLoading(true);
      const res = await fetch(`/api/paste/${id}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ password: pwd || '' }),
      });

      if (res.status === 403) {
        setError('Invalid password.');
        setLoading(false);
        return;
      }
      if (res.status === 404) {
        setError('Paste not found or expired.');
        setLoading(false);
        return;
      }

      const data = await res.json();
      setPaste(data);

      const content = data.content.toLowerCase();

      let detected = 'javascript';
      if (content.includes('select ') || content.includes('insert into')) {
        detected = 'sql';
      } else if (content.includes('function') || content.includes('const')) {
        detected = 'javascript';
      } else if (content.includes('import ') || content.includes('export ')) {
        detected = 'typescript';
      } else if (content.includes('{') && content.includes('}')) {
        detected = 'json';
      } else if (content.includes('#include') || content.includes('int main')) {
        detected = 'cpp';
      } else if (content.includes('arduino')) {
        detected = 'arduino';
      } else {
        detected = 'bash';
      }

      await loadLanguage(detected);
      setLanguage(`language-${detected}`);

      setLoading(false);
    };

    useEffect(() => {
      fetchPaste();
    }, [id]);

    useEffect(() => {
      if (paste?.content) Prism.highlightAll();
    }, [paste, language]);

    if (loading) return <LoadingPaste />;

    if (error || (paste?.protected && !paste?.content)) {
      return <PasswordForm error={error} onSubmit={(pwd) => fetchPaste(pwd)} />;
    }

    return (
      <div className="relative w-screen h-screen bg-[#0e0f13] text-white flex overflow-hidden">
        <CodeViewer paste={paste} language={language} />
        <PasteSidebar paste={paste} id={id} />
        <AuthSection />
      </div>
    );
  }


