import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { useState } from 'react' import { Helmet } from 'react-helmet-async' import { useLocale } from '@/lib/useLocale' import FormField from '@/components/common/FormField' import PageTitle from '@/components/common/PageTitle' import MainArea from '@/components/layout/MainArea' import { Button } from '@/components/ui/button' import { toast } from '@/components/ui/use-toast' import { SITE_TITLE } from '@/config' import { createMaterialSyncSuppression, fetchMaterialSyncSuppressions } from '@/lib/materials' import { materialsKeys } from '@/lib/queryKeys' import { localisedDateString, inputClass } from '@/lib/utils' import { useUITranslation } from '@/lib/useUITranslation' import type { FC, FormEvent } from 'react' import type { MaterialSyncSuppressionSourceKind } from '@/types' const SOURCE_KIND_LABELS: Record = { uri: 'suppressions.sources.uri', google_drive_path: 'suppressions.sources.google_drive_path', google_drive_path_prefix: 'suppressions.sources.google_drive_path_prefix', google_drive_file: 'suppressions.sources.google_drive_file', legacy_drive_path: 'suppressions.sources.legacy_drive_path', legacy_drive_path_prefix: 'suppressions.sources.legacy_drive_path_prefix' } const REASONS = [ 'copyright_high_risk', 'copyright_takedown', 'adult_or_sensitive', 'personal_information', 'malware_or_dangerous_file', 'duplicate_or_low_quality', 'source_owner_request', 'other'] as const type MaterialSyncSuppressionReason = typeof REASONS[number] const MaterialSyncSuppressionsPage: FC = () => { const locale = useLocale () const { message, label } = useUITranslation ('materials') const qc = useQueryClient () const [sourceKind, setSourceKind] = useState ('uri') const [sourceUri, setSourceUri] = useState ('') const [drivePath, setDrivePath] = useState ('') const [driveFileId, setDriveFileId] = useState ('') const [reason, setReason] = useState (REASONS[0]) const { data, isError, isLoading } = useQuery ({ queryKey: materialsKeys.suppressions (locale), queryFn: () => fetchMaterialSyncSuppressions (locale)}) const createMutation = useMutation ({ mutationFn: async () => await createMaterialSyncSuppression ({ sourceKind, sourceUri, drivePath, driveFileId, reason}, locale), onSuccess: async () => { await qc.invalidateQueries ({ queryKey: materialsKeys.suppressions (locale) }) await qc.invalidateQueries ({ queryKey: materialsKeys.root }) setSourceUri ('') setDrivePath ('') setDriveFileId ('') toast ({ title: label ('suppressions.registered') }) }, onError: () => { toast ({ title: label ('suppressions.registerFailed') }) }}) const handleSubmit = (event: FormEvent) => { event.preventDefault () createMutation.mutate () } const suppressions = data?.suppressions ?? [] return ( {message ('suppressions.title').text} | {SITE_TITLE}
{label ('suppressions.heading')}
{({ invalid }) => ( )} {({ invalid }) => ( setSourceUri (e.target.value)} className={inputClass (invalid)}/>)} {({ invalid }) => ( setDrivePath (e.target.value)} className={inputClass (invalid)}/>)} {({ invalid }) => ( setDriveFileId (e.target.value)} className={inputClass (invalid)}/>)} {({ invalid }) => ( )}
{isLoading &&

{label ('common:loading')}

} {isError && (

{label ('suppressions.error')}

)}
{suppressions.map (suppression => (
{label (SOURCE_KIND_LABELS[suppression.sourceKind])}
{suppression.normalizedSourceKey}
{label ('suppressions.reasonPrefix')} {REASONS.includes (suppression.reason as MaterialSyncSuppressionReason) ? label (`suppressions.reasons.${suppression.reason}`) : suppression.reason} /{' '} {label ('suppressions.registeredPrefix')}
))}
) } export default MaterialSyncSuppressionsPage