2025-08-20 14:14:33 +02:00
|
|
|
'use client';
|
|
|
|
|
|
|
|
|
|
import { useRouter } from 'next/navigation';
|
|
|
|
|
import Prism from 'prismjs';
|
2025-08-20 15:16:00 +02:00
|
|
|
import { use, useEffect, useState } from 'react';
|
|
|
|
|
|
2025-08-20 14:14:33 +02:00
|
|
|
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';
|
2025-08-20 15:16:00 +02:00
|
|
|
import 'prismjs/themes/prism-tomorrow.css';
|
2025-08-20 14:14:33 +02:00
|
|
|
|
2025-08-20 15:16:00 +02:00
|
|
|
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();
|
2025-08-20 14:14:33 +02:00
|
|
|
|
|
|
|
|
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);
|
2025-08-20 15:16:00 +02:00
|
|
|
const res = await fetch(`/api/paste/${id}`, {
|
2025-08-20 14:14:33 +02:00
|
|
|
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
|
2025-08-20 15:16:00 +02:00
|
|
|
}, [id]);
|
2025-08-20 14:14:33 +02:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (paste?.content) {
|
|
|
|
|
Prism.highlightAll();
|
|
|
|
|
}
|
|
|
|
|
}, [paste]);
|
|
|
|
|
|
|
|
|
|
if (loading) return <LoadingPaste />;
|
|
|
|
|
|
|
|
|
|
if (error || (paste?.protected && !paste?.content)) {
|
2025-08-20 15:16:00 +02:00
|
|
|
return <PasswordForm error={error} onSubmit={(pwd) => fetchPaste(pwd)} />;
|
2025-08-20 14:14:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="relative w-screen h-screen bg-[#0e0f13] text-white flex overflow-hidden">
|
2025-08-20 15:16:00 +02:00
|
|
|
<CodeViewer paste={paste} language={language} />
|
|
|
|
|
<PasteSidebar paste={paste} id={id} />
|
|
|
|
|
<AuthSection />
|
2025-08-20 14:14:33 +02:00
|
|
|
</div>
|
|
|
|
|
);
|
2025-08-20 15:16:00 +02:00
|
|
|
|
2025-08-20 14:14:33 +02:00
|
|
|
}
|