From 634ab7de1f18c922ef0c49353fdeab92847a4afc Mon Sep 17 00:00:00 2001 From: Andrew Cassidy Date: Tue, 12 Dec 2023 21:47:47 -0700 Subject: [PATCH] fix: autocomplete from scryfall, checkbox id, token expiration (#450) --- .../CardSubmission/CardSubmission.tsx | 16 ++++++++++------ frontend/services/card.service.ts | 18 ++++++++++++++++++ frontend/services/template.service.ts | 4 ++-- frontend/services/token.service.ts | 8 ++++---- frontend/types/api.ts | 7 +++++++ 5 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 frontend/services/card.service.ts diff --git a/frontend/components/submission/CardSubmission/CardSubmission.tsx b/frontend/components/submission/CardSubmission/CardSubmission.tsx index f4705ca4cf..417fd1b25c 100644 --- a/frontend/components/submission/CardSubmission/CardSubmission.tsx +++ b/frontend/components/submission/CardSubmission/CardSubmission.tsx @@ -3,6 +3,7 @@ import AutocompleteInput from "../../advancedSearch/AutocompleteInput/Autocomple import {useEffect, useState} from "react"; import Select, {MultiValue} from 'react-select' import TemplateService from "../../../services/template.service"; +import CardService from "../../../services/card.service"; const ZONE_OPTIONS = [ {value: 'H', label: 'Hand'}, @@ -21,15 +22,13 @@ type Props = { index: number template?: boolean } - -const cardAutocompleteOptions = (require("../../../../autocomplete-data/cards.json")).map((card: any) => ({value: card.label, label: card.label})) -// const cardAutocompleteOptions = require("../../../../autocomplete-data/cards.json") const CardSubmission = ({card, onChange, index, onDelete, template}: Props) => { const [nameInput, setNameInput] = useState(card.card || '') const [templateInput, setTemplateInput] = useState(card.template || '') const [templateOptions, setTemplateOptions] = useState>([]) const [templatesLoading, setTemplatesLoading] = useState(false) + const [cardAutocompleteOptions, setCardAutocompleteOptions] = useState>([]) const handleZoneChange = (zoneLocations: MultiValue<{value: string, label: string}>) => { const newZoneList = zoneLocations.map(zone => zone.value) @@ -52,7 +51,7 @@ const CardSubmission = ({card, onChange, index, onDelete, template}: Props) => { setTemplatesLoading(true) TemplateService.getTemplates(value) .then(response => { - setTemplateOptions(response.results.map(template => ({value: template.template, label: template.template}))) + setTemplateOptions(response.results.map(template => ({value: template.name, label: template.name}))) setTemplatesLoading(false) }).catch(e => console.error(e)) @@ -63,6 +62,11 @@ const CardSubmission = ({card, onChange, index, onDelete, template}: Props) => { onChange({...card as SubmissionCardType, card: value}) } + useEffect(() => { + CardService.getCardNames() + .then(names => setCardAutocompleteOptions(names.map(name => ({value: name, label: name})))) + }, []) + return (
@@ -174,12 +178,12 @@ const CardSubmission = ({card, onChange, index, onDelete, template}: Props) => {
onChange({...card, mustBeCommander: !card.mustBeCommander})} type="checkbox" /> - +
) diff --git a/frontend/services/card.service.ts b/frontend/services/card.service.ts new file mode 100644 index 0000000000..5b7933d3c3 --- /dev/null +++ b/frontend/services/card.service.ts @@ -0,0 +1,18 @@ +import requestService from "./request.service"; + +let cachedNames: string[] | null = null +const SCRYFALL_NAME_URL = 'https://api.scryfall.com/catalog/card-names' +const getCardNames = async (): Promise => { + if (cachedNames) return cachedNames + const res = await requestService.get(SCRYFALL_NAME_URL) + const data = res.data as string[] + const processedNames = data.filter(n => !n.includes('A-')).map(n => n.split(' // ')[0]) + cachedNames = processedNames + return processedNames +} + +const CardService = { + getCardNames +} + +export default CardService diff --git a/frontend/services/template.service.ts b/frontend/services/template.service.ts index c6f5d3a5e9..c0615c4324 100644 --- a/frontend/services/template.service.ts +++ b/frontend/services/template.service.ts @@ -1,9 +1,9 @@ import requestService from "./request.service"; import {TemplateSubmissionType} from "../types/submission"; -import {PaginatedResponse} from "../types/api"; +import {PaginatedResponse, TemplateResponseType} from "../types/api"; const getTemplates = async (name: string) => { - return requestService.get>(`/api/templates/?q=${name}`) + return requestService.get>(`/api/templates/?q=${name}`) } const TemplateService = { diff --git a/frontend/services/token.service.ts b/frontend/services/token.service.ts index 43b0afb2bb..48402adc88 100644 --- a/frontend/services/token.service.ts +++ b/frontend/services/token.service.ts @@ -50,7 +50,7 @@ function getToken(): Promise { if (!decodedToken) return fetchNewToken().then(setToken) if (decodedToken.exp > expirationCutoff) { - CookieService.set('csbJwt', jwt) + CookieService.set('csbJwt', jwt, 'day') return jwt } @@ -75,7 +75,7 @@ function getTokenFromServerContext( if (!decodedToken) return fetchNewToken(refreshToken).then(setToken) if (decodedToken.exp > expirationCutoff) { - CookieService.set('csbJwt', jwt) + CookieService.set('csbJwt', 'day') return jwt } @@ -86,8 +86,8 @@ function getTokenFromServerContext( function setToken({ access, refresh }: RefreshResponse) { const jwt = access - CookieService.set('csbJwt', jwt) - if (refresh) CookieService.set('csbRefresh', refresh) + CookieService.set('csbJwt', jwt, 'day') + if (refresh) CookieService.set('csbRefresh', refresh, 'day') return jwt } diff --git a/frontend/types/api.ts b/frontend/types/api.ts index 905f7018ce..7cd9759b90 100644 --- a/frontend/types/api.ts +++ b/frontend/types/api.ts @@ -4,3 +4,10 @@ export type PaginatedResponse = { previous: string | null results: T[] } + +export type TemplateResponseType = { + id: number + name: string + scryfallApi: string + scryfallQuery: string +}