diff --git a/api/carousel/carouselKeys.ts b/api/carousel/carouselKeys.ts index 4d4a4d7..c539516 100644 --- a/api/carousel/carouselKeys.ts +++ b/api/carousel/carouselKeys.ts @@ -1,7 +1,10 @@ +import { CarouselSlideParams } from "@/models/carousel/carouselSlide" + export const CAROUSEL_QUERY_KEYS = Object.freeze({ CAROUSEL: 'carousel', SLIDES: 'slides', GET: 'get', + GET_RAW: 'get-raw', CREATE: 'create', UPDATE: 'update', IMAGE: 'image', @@ -16,4 +19,10 @@ export const carouselKeys = Object.freeze({ CAROUSEL_QUERY_KEYS.GET, `${id}`, ], + getRaw: (id: string | number, params?:CarouselSlideParams) => [ + CAROUSEL_QUERY_KEYS.CAROUSEL, + CAROUSEL_QUERY_KEYS.SLIDES, + CAROUSEL_QUERY_KEYS.GET_RAW, + `${id}`, + ], }) diff --git a/api/carousel/queries/useFetchCarouselSlides.ts b/api/carousel/queries/useFetchCarouselSlides.ts index 0d3a469..5e16411 100644 --- a/api/carousel/queries/useFetchCarouselSlides.ts +++ b/api/carousel/queries/useFetchCarouselSlides.ts @@ -11,11 +11,11 @@ const fetchCarouselSlides = async (params?:CarouselSlideParams): Promise { +export const useFetchCarouselSlides = () => { const toaster = useToaster() return useQuery({ - queryFn: ()=>fetchCarouselSlides(params), + queryFn: ()=>fetchCarouselSlides(), queryKey: carouselKeys.getMany, staleTime: 1000 * 60 * 10, // stale for 10 minutes onError: toaster.onQueryError, diff --git a/api/carousel/queries/useFetchRawCarouselSlides.ts b/api/carousel/queries/useFetchRawCarouselSlides.ts new file mode 100644 index 0000000..870e17f --- /dev/null +++ b/api/carousel/queries/useFetchRawCarouselSlides.ts @@ -0,0 +1,23 @@ +import { carouselKeys, CAROUSEL_QUERY_KEYS } from 'api/carousel/carouselKeys' +import { useToaster } from 'providers/ToastProvider' +import { CarouselSlide, CarouselSlideParams } from 'models/carousel/carouselSlide' +import { useQuery } from 'react-query' +import http from 'api/http' + +const { CAROUSEL, SLIDES, GET_RAW } = CAROUSEL_QUERY_KEYS + +const fetchRawCarouselSlides = async (params?:CarouselSlideParams): Promise => { + const response = await http.get(`${CAROUSEL}/${SLIDES}/${GET_RAW}`,{params}) + return response.data +} + +export const useFetchRawCarouselSlides = (params?:CarouselSlideParams) => { + const toaster = useToaster() + + return useQuery({ + queryFn: ()=>fetchRawCarouselSlides(params), + queryKey: carouselKeys.getMany, + staleTime: 1000 * 60 * 10, // stale for 10 minutes + onError: toaster.onQueryError, + }) +} diff --git a/app/(authenticated)/admin/carousel-slides/[id]/edit/page.tsx b/app/(authenticated)/admin/carousel-slides/[id]/edit/page.tsx index 67f27cf..f0024a2 100644 --- a/app/(authenticated)/admin/carousel-slides/[id]/edit/page.tsx +++ b/app/(authenticated)/admin/carousel-slides/[id]/edit/page.tsx @@ -22,11 +22,7 @@ import { useFetchComics, useFetchRawComic } from '@/api/comic' import { Role } from '@/enums/role' import { useFetchMe } from '@/api/creator' import SearchInput from '@/components/forms/SearchInput' - -type SearchInputOption = { - value: string | number; - label: string; -} +import { CarouselSlideSearchInputOption } from '@/types/carouseSlideSearchInputOption' interface Params { id: string | number @@ -123,7 +119,7 @@ export default function CreateCarouselSlidePage({ params }: { params: Params }){ ({ value: issue.id, label: issue.title }))} value={searchComicIssue} - onChange={(value:string, option?:SearchInputOption) => { + onChange={(value:string, option?:CarouselSlideSearchInputOption) => { setSearchComicIssue(value); if (option) { handleChangeComicIssue(option.value as number, option.label); @@ -138,7 +134,7 @@ export default function CreateCarouselSlidePage({ params }: { params: Params }){ ({ value: comic.slug, label: comic.title }))} value={searchComic} - onChange={(value:string, option?:SearchInputOption) => { + onChange={(value:string, option?:CarouselSlideSearchInputOption) => { setSearchComic(value); if (option) { handleChangeComic(option.value as string, option.label); diff --git a/app/(authenticated)/admin/carousel-slides/create/page.tsx b/app/(authenticated)/admin/carousel-slides/create/page.tsx index 3fad542..512ec10 100644 --- a/app/(authenticated)/admin/carousel-slides/create/page.tsx +++ b/app/(authenticated)/admin/carousel-slides/create/page.tsx @@ -25,13 +25,13 @@ import { useFetchComics } from '@/api/comic' import { useFetchMe } from '@/api/creator' import { Role } from '@/enums/role' import CustomDatePicker from '@/components/forms/CustomDatePicker' +import SearchInput from '@/components/forms/SearchInput' +import { CarouselSlideSearchInputOption } from '@/types/carouseSlideSearchInputOption' export default function CreateCarouselSlidePage() { const toaster = useToaster() const [searchComicIssue, setSearchComicIssue] = useState('') const [searchComic, setSearchComic] = useState('') - const [isSearchingIssues, setIsSearchingIssues] = useState(false) - const [isSearchingComics, setIsSearchingComics] = useState(false) const { flatData: comicIssues } = useFetchComicIssues({ titleSubstring: searchComicIssue, skip: 0, take: 10 }) const { flatData: comics } = useFetchComics({ titleSubstring: searchComic, skip: 0, take: 10 }) @@ -76,13 +76,11 @@ export default function CreateCarouselSlidePage() { const handleChangeComicIssue = async (value: number, title: string) => { setValue('comicIssueId', value) setSearchComicIssue(title) - setIsSearchingIssues(false) } const handleChangeComic = async (value: string, title: string) => { setValue('comicSlug', value) setSearchComic(title) - setIsSearchingComics(false) } const handleChangeLocation = (value: string) => { @@ -115,50 +113,34 @@ export default function CreateCarouselSlidePage() {
-
setIsSearchingIssues(false)}> - setIsSearchingIssues(true)} - onChange={(e) => { - setSearchComicIssue(e.target.value) - }} - /> - {isSearchingIssues - ? comicIssues.map((issue) => ( -

handleChangeComicIssue(issue.id, issue.title)} - > - {issue.title} -

- )) - : null} -
-
setIsSearchingComics(false)}> - Comic Issue + ({ value: issue.id, label: issue.title }))} + value={searchComicIssue} + onChange={(value:string, option?:CarouselSlideSearchInputOption) => { + setSearchComicIssue(value); + if (option) { + handleChangeComicIssue(option.value as number, option.label); + } + }} + onInputChange={setSearchComicIssue} + placeholder="Select Comic Issues" + /> +
+ + ({ value: comic.slug, label: comic.title }))} value={searchComic} - type='text' - placeholder='Select Comics' - onChange={(e) => { - setSearchComic(e.target.value) + onChange={(value:string, option?:CarouselSlideSearchInputOption) => { + setSearchComic(value); + if (option) { + handleChangeComic(option.value as string, option.label); + } }} - onMouseEnter={() => setIsSearchingComics(true)} - /> - {isSearchingComics - ? comics.map((comic) => ( -

handleChangeComic(comic.slug, comic.title)} - > - {comic.title} -

- )) - : null} -
+ onInputChange={setSearchComic} + placeholder="Select Comics" + /> +
diff --git a/app/(authenticated)/admin/carousel-slides/page.tsx b/app/(authenticated)/admin/carousel-slides/page.tsx index 74a8d5e..76f78a9 100644 --- a/app/(authenticated)/admin/carousel-slides/page.tsx +++ b/app/(authenticated)/admin/carousel-slides/page.tsx @@ -7,13 +7,14 @@ import CircularProgress from '@mui/material/CircularProgress' import SkeletonImage from '@/components/SkeletonImage' import ButtonLink from '@/components/ButtonLink' import { RoutePath } from '@/enums/routePath' -import { useExpireCarouselSlide, useFetchCarouselSlides } from '@/api/carousel' +import { useExpireCarouselSlide } from '@/api/carousel' import { useFetchMe } from '@/api/creator' import { Role } from '@/enums/role' import { Button } from '@mui/material' +import { useFetchRawCarouselSlides } from '@/api/carousel/queries/useFetchRawCarouselSlides' export default function CarouselSlidePage() { - const {data: carouselSlides, isLoading: isLoadingCarouselSlides} = useFetchCarouselSlides({getExpired:true}) + const {data: carouselSlides, isLoading: isLoadingCarouselSlides} = useFetchRawCarouselSlides({isExpired:true}) useAuthenticatedRoute() const { mutateAsync: expireCarouselSlide } = useExpireCarouselSlide(); diff --git a/components/forms/schemas.ts b/components/forms/schemas.ts index 3eae80c..95a12cb 100644 --- a/components/forms/schemas.ts +++ b/components/forms/schemas.ts @@ -167,7 +167,7 @@ export const createCarouselSlideValidationSchema = yup.object().shape({ image: yup.mixed(), title: yup .string() - .max(26, generateMaxLengthErrorMessage('title', 26)), + .max(64, generateMaxLengthErrorMessage('title', 64)), priority: yup .number() .required(yupRequiredMessage('Priority number')) @@ -176,7 +176,7 @@ export const createCarouselSlideValidationSchema = yup.object().shape({ .min(1, generateMinNumberErrorMessage('Priority number', 1)), subtitle: yup .string() - .max(48, generateMaxLengthErrorMessage('title', 48)), + .max(256, generateMaxLengthErrorMessage('subtitle', 256)), location: yup.string().required(yupRequiredMessage('Carousel Location')), comicIssueId: yup.number(), comicSlug: yup.string(), diff --git a/models/carousel/carouselSlide.ts b/models/carousel/carouselSlide.ts index 1f05171..4b0a52c 100644 --- a/models/carousel/carouselSlide.ts +++ b/models/carousel/carouselSlide.ts @@ -38,5 +38,5 @@ export type UpdateCarouselSlideData = Partial< > export interface CarouselSlideParams { - getExpired?:boolean + isExpired?:boolean } \ No newline at end of file diff --git a/types/carouseSlideSearchInputOption.ts b/types/carouseSlideSearchInputOption.ts new file mode 100644 index 0000000..7f1b94e --- /dev/null +++ b/types/carouseSlideSearchInputOption.ts @@ -0,0 +1,4 @@ +export type CarouselSlideSearchInputOption = { + value: string | number; + label: string; +} \ No newline at end of file