upd
This commit is contained in:
@@ -7,7 +7,7 @@ function ModalContainer() {
|
||||
return (
|
||||
<div
|
||||
// onClick={() => setModal(null)}
|
||||
className={`fixed p-8 top-0 left-0 w-full h-full flex justify-center items-center bg-black bg-opacity-80 overflow-auto transition-opacity`}
|
||||
className={`fixed p-8 top-0 left-0 z-10 w-full h-full flex justify-center items-center bg-black bg-opacity-80 overflow-auto transition-opacity`}
|
||||
>
|
||||
<div onClick={(e) => e.stopPropagation()} className="cursor-default">
|
||||
{modal}
|
||||
|
||||
@@ -28,7 +28,7 @@ function ProjectCard({
|
||||
<div
|
||||
className="group-hover:scale-110 transition-transform duration-500 absolute top-0 left-0 w-full h-full bg-cover bg-center bg-no-repeat"
|
||||
style={{
|
||||
backgroundImage: `url(${import.meta.env.VITE_API_URL}/api/upload/${image})`,
|
||||
backgroundImage: `url(${import.meta.env.VITE_API_URL}/upload/${image})`,
|
||||
}}
|
||||
></div>
|
||||
<div className="absolute top-0 left-0 w-full h-full bg-gradient-card"></div>
|
||||
|
||||
@@ -44,7 +44,7 @@ function CreateProjectModal() {
|
||||
|
||||
setProject((prev) => ({
|
||||
...prev,
|
||||
image: `${import.meta.env.VITE_API_URL}/api/${file}`,
|
||||
image: file,
|
||||
}));
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
@@ -143,7 +143,9 @@ function CreateProjectModal() {
|
||||
className="absolute opacity-0"
|
||||
onChange={handleChangeFile}
|
||||
/>
|
||||
<p>{file ? file.name : "Выберите изображение"}</p>
|
||||
<p className="truncate">
|
||||
{file ? file.name : "Выберите изображение"}
|
||||
</p>
|
||||
|
||||
{previewFile && <img src={previewFile} alt="" />}
|
||||
</label>
|
||||
|
||||
@@ -42,13 +42,13 @@ function EditProjectModal({ projectId }: EditProjectModalProps) {
|
||||
formData.append("file", file);
|
||||
|
||||
try {
|
||||
const { file: url }: { file: string } = await api
|
||||
const { file }: { file: string } = await api
|
||||
.post("upload", { body: formData })
|
||||
.json();
|
||||
|
||||
setProject((prev) => ({
|
||||
...prev,
|
||||
image: `${import.meta.env.VITE_API_URL}/api/${url}`,
|
||||
image: file,
|
||||
}));
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
@@ -161,12 +161,17 @@ function EditProjectModal({ projectId }: EditProjectModalProps) {
|
||||
className="absolute opacity-0"
|
||||
onChange={handleChangeFile}
|
||||
/>
|
||||
<p>{file ? file.name : "Выберите изображение"}</p>
|
||||
<p className="truncate">{file ? file.name : "Выберите изображение"}</p>
|
||||
|
||||
{previewFile ? (
|
||||
<img src={previewFile} alt="" />
|
||||
) : (
|
||||
project.image && <img src={project.image} alt="" />
|
||||
project.image && (
|
||||
<img
|
||||
src={`${import.meta.env.VITE_API_URL}/upload/${project.image}`}
|
||||
alt=""
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</label>
|
||||
|
||||
|
||||
+6
-6
@@ -1,18 +1,18 @@
|
||||
import ReactDOM from "react-dom/client";
|
||||
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
||||
import App from "./App.tsx";
|
||||
import "./index.css";
|
||||
// import ProjectsPage from "./pages/ProjectsPage.tsx";
|
||||
import App from "./App.tsx";
|
||||
import ProjectsPage from "./pages/ProjectsPage.tsx";
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
path: "/",
|
||||
element: <App />,
|
||||
},
|
||||
// {
|
||||
// path: "/projects",
|
||||
// element: <ProjectsPage />,
|
||||
// },
|
||||
{
|
||||
path: "/projects",
|
||||
element: <ProjectsPage />,
|
||||
},
|
||||
]);
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
|
||||
@@ -34,12 +34,12 @@ function ProjectsPage() {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen 2xl:px-10 xl:px-8 sm:px-6 px-4 overflow-x-clip">
|
||||
<div className="relative conatiner mx-auto 2xl:max-w-screen-2xl">
|
||||
<div className="py-8 flex flex-col gap-8">
|
||||
<Button onClick={handleClickCreateProject}>
|
||||
Добавить проект
|
||||
</Button>
|
||||
<div className="min-h-screen">
|
||||
<div className="fixed top-0 left-0 z-10 p-4 bg-[#14161F] border-b border-white border-opacity-10 w-full shadow-2xl">
|
||||
<Button onClick={handleClickCreateProject}>Добавить проект</Button>
|
||||
</div>
|
||||
<div className="conatiner mx-auto 2xl:px-10 xl:px-8 sm:px-6 px-4 2xl:max-w-screen-2xl mt-20">
|
||||
<div className="relative py-8 flex flex-col gap-8">
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
{projects.map((project, index) => (
|
||||
<div key={index} className="relative">
|
||||
@@ -49,17 +49,49 @@ function ProjectsPage() {
|
||||
onClick={() =>
|
||||
setModal(<EditProjectModal projectId={project.id!} />)
|
||||
}
|
||||
className="px-3 py-2 border bg-black bg-opacity-60 hover:bg-opacity-70 transition-opacity"
|
||||
className="group relative p-2 bg-black bg-opacity-60 hover:bg-opacity-70 transition-opacity rounded-full"
|
||||
>
|
||||
Редактировать
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="w-6 h-6"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"
|
||||
/>
|
||||
</svg>
|
||||
<span className="pointer-events-none group-hover:opacity-100 opacity-0 transition-opacity absolute -bottom-[90%] left-[50%] -translate-x-[50%] bg-neutral-900 px-2 py-1 text-sm rounded-lg">
|
||||
Редактировать
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() =>
|
||||
setModal(<DeleteProjectModal projectId={project.id!} />)
|
||||
}
|
||||
className="px-3 py-2 border bg-black bg-opacity-60 hover:bg-opacity-70 transition-opacity"
|
||||
className="group relative p-2 bg-black bg-opacity-60 hover:bg-opacity-70 transition-opacity rounded-full"
|
||||
>
|
||||
Удалить
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="w-6 h-6"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"
|
||||
/>
|
||||
</svg>
|
||||
<span className="pointer-events-none group-hover:opacity-100 opacity-0 transition-opacity absolute -bottom-[90%] left-[50%] -translate-x-[50%] bg-neutral-900 px-2 py-1 text-sm rounded-lg">
|
||||
Удалить
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
function TestPage() {
|
||||
return (
|
||||
<video
|
||||
src="https://graff.estate/videos/features/nks_infra.mp4"
|
||||
preload="metadata"
|
||||
className="video-loader"
|
||||
></video>
|
||||
);
|
||||
}
|
||||
|
||||
export default TestPage;
|
||||
@@ -1,7 +1,7 @@
|
||||
import ky from "ky";
|
||||
|
||||
const api = ky.extend({
|
||||
prefixUrl: `${import.meta.env.VITE_API_URL}/api`,
|
||||
prefixUrl: import.meta.env.VITE_API_URL,
|
||||
});
|
||||
|
||||
export default api;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export default function randomNumber(min: number, max: number) {
|
||||
return Math.floor(Math.random() * (max - min) + min);
|
||||
}
|
||||
Reference in New Issue
Block a user