js -> ts
This commit is contained in:
@@ -5,19 +5,46 @@ import { Button } from "@mui/joy";
|
||||
import { AutoComplete } from "primereact/autocomplete";
|
||||
import { InputText } from "primereact/inputtext";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
_t?: string;
|
||||
}
|
||||
}
|
||||
|
||||
type MediaType = 'movie' | 'tv' | string;
|
||||
|
||||
interface SearchItem {
|
||||
label: string;
|
||||
year?: string;
|
||||
mediaType?: MediaType;
|
||||
poster_path?: string | null;
|
||||
overview?: string;
|
||||
title?: string;
|
||||
type?: string;
|
||||
requester?: string;
|
||||
}
|
||||
|
||||
interface SubmittedRequest {
|
||||
title: string;
|
||||
year: string;
|
||||
type: string;
|
||||
requester: string;
|
||||
poster_path?: string | null;
|
||||
}
|
||||
|
||||
export default function ReqForm() {
|
||||
const [type, setType] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
const [year, setYear] = useState("");
|
||||
const [requester, setRequester] = useState("");
|
||||
const [selectedItem, setSelectedItem] = useState(null);
|
||||
const [selectedOverview, setSelectedOverview] = useState("");
|
||||
const [selectedTitle, setSelectedTitle] = useState("");
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [suggestions, setSuggestions] = useState([]);
|
||||
const [posterLoading, setPosterLoading] = useState(true);
|
||||
const [submittedRequest, setSubmittedRequest] = useState(null); // Track successful submission
|
||||
const [csrfToken, setCsrfToken] = useState(null);
|
||||
const [type, setType] = useState<string>("");
|
||||
const [title, setTitle] = useState<string>("");
|
||||
const [year, setYear] = useState<string>("");
|
||||
const [requester, setRequester] = useState<string>("");
|
||||
const [selectedItem, setSelectedItem] = useState<SearchItem | null>(null);
|
||||
const [selectedOverview, setSelectedOverview] = useState<string>("");
|
||||
const [selectedTitle, setSelectedTitle] = useState<string>("");
|
||||
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
|
||||
const [suggestions, setSuggestions] = useState<SearchItem[]>([]);
|
||||
const [posterLoading, setPosterLoading] = useState<boolean>(true);
|
||||
const [submittedRequest, setSubmittedRequest] = useState<SubmittedRequest | null>(null); // Track successful submission
|
||||
const [csrfToken, setCsrfToken] = useState<string | null>(null);
|
||||
|
||||
// Get CSRF token from window global on mount
|
||||
useEffect(() => {
|
||||
@@ -36,7 +63,7 @@ export default function ReqForm() {
|
||||
}
|
||||
}, [title, selectedTitle, selectedOverview, selectedItem, type]);
|
||||
|
||||
const searchTitles = async (event) => {
|
||||
const searchTitles = async (event: { query: string }) => {
|
||||
const query = event.query;
|
||||
if (query.length < 2) {
|
||||
setSuggestions([]);
|
||||
@@ -48,7 +75,7 @@ export default function ReqForm() {
|
||||
if (!response.ok) {
|
||||
throw new Error(`API error: ${response.status}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
const data: SearchItem[] = await response.json();
|
||||
setSuggestions(data);
|
||||
} catch (error) {
|
||||
console.error('Error fetching suggestions:', error);
|
||||
@@ -56,7 +83,7 @@ export default function ReqForm() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
if (!title.trim()) {
|
||||
toast.error("Please fill in the required fields.");
|
||||
@@ -101,7 +128,7 @@ export default function ReqForm() {
|
||||
year,
|
||||
type,
|
||||
requester,
|
||||
poster_path: selectedItem?.poster_path,
|
||||
poster_path: selectedItem?.poster_path ?? null,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Submission error:', error);
|
||||
@@ -126,13 +153,13 @@ export default function ReqForm() {
|
||||
|
||||
const attachScrollFix = () => {
|
||||
setTimeout(() => {
|
||||
const panel = document.querySelector(".p-autocomplete-panel");
|
||||
const items = panel?.querySelector(".p-autocomplete-items");
|
||||
const panel = document.querySelector<HTMLElement>(".p-autocomplete-panel");
|
||||
const items = panel?.querySelector<HTMLElement>(".p-autocomplete-items");
|
||||
if (items) {
|
||||
items.style.maxHeight = "200px";
|
||||
items.style.overflowY = "auto";
|
||||
items.style.overscrollBehavior = "contain";
|
||||
const wheelHandler = (e) => {
|
||||
const wheelHandler = (e: WheelEvent) => {
|
||||
const delta = e.deltaY;
|
||||
const atTop = items.scrollTop === 0;
|
||||
const atBottom = items.scrollTop + items.clientHeight >= items.scrollHeight;
|
||||
@@ -148,7 +175,7 @@ export default function ReqForm() {
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const formatMediaType = (mediaTypeValue) => {
|
||||
const formatMediaType = (mediaTypeValue: MediaType | undefined) => {
|
||||
if (!mediaTypeValue) return "";
|
||||
if (mediaTypeValue === "tv") return "TV Series";
|
||||
if (mediaTypeValue === "movie") return "Movie";
|
||||
@@ -239,16 +266,17 @@ export default function ReqForm() {
|
||||
delay={300}
|
||||
onChange={(e) => {
|
||||
// Handle both string input and object selection
|
||||
const val = e.target?.value ?? e.value;
|
||||
setTitle(typeof val === 'string' ? val : val?.label || '');
|
||||
const val = (e as any).target?.value ?? e.value;
|
||||
setTitle(typeof val === 'string' ? val : (val as SearchItem | undefined)?.label || '');
|
||||
}}
|
||||
onSelect={(e) => {
|
||||
setType(e.value.mediaType === 'tv' ? 'tv' : 'movie');
|
||||
setTitle(e.value.label);
|
||||
setSelectedTitle(e.value.label);
|
||||
setSelectedItem(e.value);
|
||||
if (e.value.year) setYear(e.value.year);
|
||||
setSelectedOverview(e.value.overview || "");
|
||||
onSelect={(e: { value: SearchItem }) => {
|
||||
const item = e.value;
|
||||
setType(item.mediaType === 'tv' ? 'tv' : 'movie');
|
||||
setTitle(item.label);
|
||||
setSelectedTitle(item.label);
|
||||
setSelectedItem(item);
|
||||
if (item.year) setYear(item.year);
|
||||
setSelectedOverview(item.overview || "");
|
||||
}}
|
||||
placeholder="Enter movie or TV title"
|
||||
title="Enter movie or TV show title"
|
||||
|
||||
Reference in New Issue
Block a user