Что я хочу: < /p>
загрузить из URL без повторной загрузки файла. < /li>
< /ol>
Когда я загружаю файл (видео, изображение или подзаголовок), он мгновенно показывает, что предварительно выключает в таблице. исчезает, но URL -файл все еще находится в состоянии (uploaddetails).
Если я снова нажимаю на загрузку, форма все еще содержит правильный URL -адрес файла - это просто предварительный просмотр, который исчезает. Предоставляя все мои межсековые файлы, поэтому, пожалуйста, помогите мне исправить это
Проблема в видео :: gdrive
Полный код: код
Strong>showupload.jsx
Strong>showupload.jsx>
import { useEffect, useState } from "react";
import { Separator } from "@/components/ui/separator";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { ShowBasicDetails } from "./tabs/ShowBasicDetails";
import { ShowFileUpload } from "./tabs/showFileUpload";
import { ScrollArea } from "../../ui/scroll-area";
import { Button } from "../../ui/button";
import { toast } from "react-hot-toast";
import {
FINAL_initialState,
FINAL_showVideoInitialFormData,
} from "../../../config/formFields";
export const ShowUpload = () => {
const [activeTab, setActiveTab] = useState("showDetails");
const [showDetailsData, setShowDetailsData] = useState(FINAL_initialState);
const [UploadDetailsData, setUploadDetailsData] = useState({});
const [category, setCategory] = useState("");
useEffect(() => {
setCategory(showDetailsData.category);
}, [showDetailsData.category]);
const handleNext = () => {
if (activeTab === "showDetails") {
// if (!category) {
// toast.error("Please select a category first.");
// return;
// }
setActiveTab("showUpload");
}
};
const handlePrevious = () => {
if (activeTab === "showUpload") {
setActiveTab("showDetails");
}
};
const handleCancel = () => {
toast.success("Upload Cancelled.");
setShowDetailsData(FINAL_initialState);
setUploadDetailsData({});
};
const handleUpload = () => {
const payload = {
...showDetailsData,
...UploadDetailsData,
};
console.log("FINAL DATA TO BACKEND:
toast.success("Show Uploaded Successfully!
};
return (
{/*
setActiveTab(val)}
className="w-[400px]"
>
Show Details
Show Upload
{activeTab === "showDetails" && (
)}
{activeTab === "showUpload" && (
)}
{activeTab === "showDetails" && (
Cancel
Next
)}
{activeTab === "showUpload" && (
Previous
Upload
)}
);
};
showbasicdetails.jsx
/* eslint-disable react/prop-types */
import { FINAL_showBasicFormControls } from "../../../../config/formFields";
import { AdminForm } from "../../../common/common-Form/adminForm";
export const ShowBasicDetails = ({ showDetails, setShowDetails }) => {
return (
Details
);
};
showfileupload.jsx
import { useEffect, useState } from "react";
import { Button } from "../../../ui/button";
import { Label } from "../../../ui/label";
import { Input } from "../../../ui/input";
import { X } from "lucide-react";
import { toast } from "react-hot-toast";
import { AdminFileUpload } from "../../../common/common-Form/adminFileUpload";
export const ShowFileUpload = ({
category,
UploadDetails,
setUploadDetails,
}) => {
const [episodes, setEpisodes] = useState([
{ title: "", video: null, subtitle: null },
]);
const [movie, setMovie] = useState({
video: null,
subtitle: null,
});
//
useEffect(() => {
if (category === "movie") {
setMovie({ video: null, subtitle: null });
setUploadDetails({ movie: { video: null, subtitle: null } });
} else {
setEpisodes([{ title: "", video: null, subtitle: null }]);
setUploadDetails({
episodes: [{ title: "", video: null, subtitle: null }],
});
}
}, [category]);
//
useEffect(() => {
if (category === "movie") {
setUploadDetails({ movie });
}
}, [movie]);
//
useEffect(() => {
if (category === "webseries") {
setUploadDetails({ episodes });
}
}, [episodes]);
//
const handleAddEpisode = () => {
setEpisodes([...episodes, { title: "", video: null, subtitle: null }]);
};
//
const handleRemoveEpisode = (index) => {
if (episodes.length === 1) {
toast.error("At least one episode is mandatory.");
return;
}
const updatedEpisodes = episodes.filter((_, i) => i !== index);
setEpisodes(updatedEpisodes);
};
//
const handleChange = (index, field, value) => {
const updatedEpisodes = [...episodes];
updatedEpisodes[index][field] = value;
setEpisodes(updatedEpisodes);
};
//
const handleRemoveVideo = (index) => {
const updatedEpisodes = [...episodes];
updatedEpisodes[index].video = null;
setEpisodes(updatedEpisodes);
};
if (!category) {
return "Choose Category";
}
return (
{category === "movie" ? "Upload Movie & Subtitle" : "Upload Episodes"}
{/*
{category === "movie" ? (
Upload Movie
setMovie((prev) => ({ ...prev, video: file }))}
/>
Upload Subtitle
setMovie((prev) => ({ ...prev, subtitle: file }))
}
/>
) : (
+ Add Episode
{/*
{episodes.map((episode, index) => (
key={index}
className="p-4 border rounded-md bg-gray-800 mb-4 relative"
>
{/*
{index > 0 && (
handleRemoveEpisode(index)}
>
Remove
)}
{/*
Episode {index + 1}
handleChange(index, "title", e.target.value)}
placeholder={`Episode ${index + 1} Title`}
/>
{/*
Upload Video
handleChange(index, "video", file)}
/>
{/*
{episode.video && episode.video instanceof File && (
handleRemoveVideo(index)}
>
)}
{/*
Upload Subtitle
handleChange(index, "subtitle", file)}
/>
))}
)}
);
};
adminfileupload.jsx
/* eslint-disable react/prop-types */
import { FileIcon, UploadCloudIcon, XIcon } from "lucide-react";
import { Input } from "../../ui/input";
import { useRef, useState } from "react";
import { toast } from "react-hot-toast";
export const AdminFileUpload = ({
onUpload = () => {}, //
accept = "image/*,video/*,.srt,.vtt",
text = "Upload File",
}) => {
const [file, setFile] = useState(null);
const inputRef = useRef(null);
//
function handleClick() {
if (inputRef.current) inputRef.current.click();
}
//
function handleFileChange(event) {
const selectedFile = event.target.files[0];
if (!selectedFile) {
toast.error("
return;
}
//
event.target.value = "";
//
const fileUrl = URL.createObjectURL(selectedFile);
//
setFile({
name: selectedFile.name,
url: fileUrl,
type: selectedFile.type,
size: selectedFile.size,
raw: selectedFile,
});
//
onUpload(fileUrl);
//
if (selectedFile.type.startsWith("video/")) {
toast.success("
} else if (
selectedFile.name.endsWith(".srt") ||
selectedFile.name.endsWith(".vtt")
) {
toast.success("
} else {
toast.success(`
}
}
//
function handleRemoveFile(event) {
event.stopPropagation();
setFile(null);
onUpload(""); //
toast.success("File Removed Successfully!");
}
return (
{/*
{/*
{file ? (
{/*
{/*
{file.type.startsWith("image/") && (
[img]{file.url}
className="w-full h-[150px] object-none rounded-lg "
/>
)}
{/*
{file.type.startsWith("video/") && (
)}
{/*
{(file.name.endsWith(".srt") || file.name.endsWith(".vtt")) && (
{file.name}
)}
) : (
{/*
Click to select {text}
)}
);
};
adminform.jsx
/* eslint-disable no-undef */
/* eslint-disable react-refresh/only-export-components */
/* eslint-disable react/prop-types */
import { Input } from "../../ui/input";
import { Label } from "../../ui/label";
import { Button } from "../../ui/button";
import { Textarea } from "../../ui/textarea";
import { ToggleGroup, ToggleGroupItem } from "../../ui/toggle-group";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "../../ui/select";
import { Popover, PopoverContent, PopoverTrigger } from "../../ui/popover";
import { Calendar } from "../../ui/calendar";
import { AdminFileUpload } from "./adminFileUpload";
export const AdminForm = ({ formControls = [], formData, setFormData }) => {
// Function to render inputs dynamically based on component type
function renderInputsByComponentType(getControlItem) {
let element = null;
const value = formData[getControlItem.name] || "";
switch (getControlItem.componentType) {
// Input Field
case "input":
element = (
setFormData({
...formData,
[getControlItem.name]: event.target.value,
})
}
/>
);
break;
// Select Dropdown
case "select":
element = (
setFormData({ ...formData, [getControlItem.name]: value })
}
value={value}
>
{getControlItem.options &&
getControlItem.options.map((optionItem) => (
{optionItem.label}
))}
);
break;
case "textarea":
element = (
setFormData({
...formData,
[getControlItem.name]: event.target.value,
})
}
/>
);
break;
// Toggle Group (Genre Selection)
case "toggle-group":
element = (
{getControlItem.options.map((optionItem) => (
{optionItem.label}
))}
);
break;
// Date Picker (Better Date Format)
case "date":
element = (
{formData[getControlItem.name]
? new Date(formData[getControlItem.name]).toLocaleDateString()
: "Pick a date"}
{
if (selectedDate) {
setFormData({
...formData,
[getControlItem.name]: selectedDate
.toISOString()
.split("T")[0], // Saves as YYYY-MM-DD
});
}
}}
initialFocus
/>
);
break;
// File Upload (Dynamic Accept Type)
case "file":
element = (
setFormData({
...formData,
[getControlItem.name]: fileUrl,
})
}
/>
);
break;
default:
element = (
setFormData({
...formData,
[getControlItem.name]: event.target.value,
})
}
/>
);
break;
}
return element;
}
return (
{formControls.map((controleItem) => (
{controleItem.label}
{renderInputsByComponentType(controleItem)}
))}
);
};
Подробнее здесь: https://stackoverflow.com/questions/794 ... e-persists