From 945af9fa29d23b302ba7fb56e4dc10f3d84a897f Mon Sep 17 00:00:00 2001 From: miha-bhaskaran <90109393+miha-bhaskaran@users.noreply.github.com> Date: Sat, 25 May 2024 21:21:52 -0700 Subject: [PATCH] Phs site map eslint (#74) * fixed colors and deleted the ts file for category queries * supabase fix * supabase types added * fixed eslint and prettier things for all pages pertaining to site maps --- src/app/exhibits/page.tsx | 4 +- .../userComponents/SiteMap/Control.tsx | 39 ++++++++------ .../SiteMap/ExhibitPreviewCard.tsx | 40 +++++++-------- .../SiteMap/MapInteractionHandler.tsx | 8 +-- .../userComponents/SiteMap/SiteMap.tsx | 2 +- .../SiteMap/TourPreviewCard.tsx | 19 +++++-- src/supabase/category/queries.ts | 46 ----------------- src/supabase/category/queries.tsx | 51 ++++++------------- 8 files changed, 79 insertions(+), 130 deletions(-) delete mode 100644 src/supabase/category/queries.ts diff --git a/src/app/exhibits/page.tsx b/src/app/exhibits/page.tsx index bb7300ff..622c4e6b 100644 --- a/src/app/exhibits/page.tsx +++ b/src/app/exhibits/page.tsx @@ -39,7 +39,7 @@ function App() { const y = element.getBoundingClientRect().top + window.scrollY + yOffset; // check on this offset later - window.scrollTo({ top: y, behavior: 'instant' }); + window.scrollTo({ top: y, behavior: 'auto' }); } }, 1000); } @@ -80,7 +80,6 @@ function App() { image={exhibit.image || ''} key={exhibit.id} id={exhibit.id} - web={false} /> ))} @@ -128,7 +127,6 @@ function App() { image={exhibit.image || ''} key={exhibit.id} id={exhibit.id} - web /> ))} diff --git a/src/components/userComponents/SiteMap/Control.tsx b/src/components/userComponents/SiteMap/Control.tsx index c1cce089..85205b2a 100644 --- a/src/components/userComponents/SiteMap/Control.tsx +++ b/src/components/userComponents/SiteMap/Control.tsx @@ -1,11 +1,9 @@ -/* eslint-disable jsdoc/require-returns */ -/* eslint-disable jsdoc/require-jsdoc */ import L from 'leaflet'; import React, { useState, createRef, useEffect } from 'react'; import { useMap } from 'react-leaflet'; interface ControlProps { - position: L.ControlPosition; + position: 'bottomleft' | 'bottomright' | 'topleft' | 'topright'; children?: React.ReactNode; container?: React.HTMLAttributes; prepend?: boolean; @@ -18,14 +16,22 @@ const POSITION_CLASSES = { topright: 'leaflet-top leaflet-right', }; +/** + * Custom control component for Leaflet maps using React. + * @param props - The properties object. + * @param props.position - The position of the control on the map. + * @param [props.children] - The child elements to be rendered inside the control. + * @param [props.container] - Additional HTML attributes for the control container. + * @param [props.prepend] - Whether to prepend the control to the container. + * @returns The custom control component. + */ function Control({ position, children, container, prepend, }: ControlProps): JSX.Element { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const [portalRoot, setPortalRoot] = useState( + const [portalRoot, setPortalRoot] = useState( document.createElement('div'), ); const positionClass = @@ -35,8 +41,8 @@ function Control({ /** * Whenever the control container ref is created, - * Ensure the click / scroll propagation is removed - * This way click/scroll events do not bubble down to the map + * ensure the click/scroll propagation is removed. + * This way click/scroll events do not bubble down to the map. */ useEffect(() => { if (controlContainerRef.current !== null) { @@ -46,21 +52,23 @@ function Control({ }, [controlContainerRef]); /** - * Whenever the position is changed, go ahead and get the container of the map and the first - * instance of the position class in that map container + * Whenever the position is changed, go ahead and get the container of the map + * and the first instance of the position class in that map container. */ useEffect(() => { const mapContainer = map.getContainer(); - const targetDiv = mapContainer.getElementsByClassName(positionClass); - setPortalRoot(targetDiv[0]); + const targetDiv = mapContainer.getElementsByClassName(positionClass)[0]; + if (targetDiv) { + setPortalRoot(targetDiv as HTMLElement); + } }, [positionClass, map]); /** * Whenever the portal root is complete, - * append or prepend the control container to the portal root + * append or prepend the control container to the portal root. */ useEffect(() => { - if (portalRoot !== null) { + if (portalRoot && controlContainerRef.current) { if (prepend !== undefined && prepend === true) { portalRoot.prepend(controlContainerRef.current); } else { @@ -70,8 +78,9 @@ function Control({ }, [portalRoot, prepend, controlContainerRef]); /** - * Concatenate the props.container className to the class of the control div, per leaflet's built in styles. - * Will need to change styling of component itself based on screen breakpoints + * Concatenate the props.container className to the class of the control div, + * per Leaflet's built-in styles. + * Will need to change styling of the component itself based on screen breakpoints. */ const className = `${container?.className?.concat(' ') || ''}leaflet-control`; diff --git a/src/components/userComponents/SiteMap/ExhibitPreviewCard.tsx b/src/components/userComponents/SiteMap/ExhibitPreviewCard.tsx index 6c80c793..07dc1e34 100644 --- a/src/components/userComponents/SiteMap/ExhibitPreviewCard.tsx +++ b/src/components/userComponents/SiteMap/ExhibitPreviewCard.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState, useCallback } from 'react'; -import { LatLngExpression } from 'leaflet'; -import { useMapEvents } from 'react-leaflet'; +// import { LatLngExpression } from 'leaflet'; +// import { useMapEvents } from 'react-leaflet'; import Link from 'next/link'; import Image from 'next/image'; import { ExhibitWithCategoryRow } from '../../../types/types'; @@ -14,18 +14,19 @@ interface ExhibitCardProps { /** * Props for ExhibitPreviewCard - * @typedef {Object} ExhibitCardProps - * @property {ExhibitWithCategoryRow} tour - The exhibit data. - * @property {Function} handleClose - Function to close the preview card. - * @property {Function} [handleClick] - Optional click handler for additional actions. + * tour - The exhibit data. + * handleClose - Function to close the preview card. + * [handleClick] - Optional click handler for additional actions. */ /** * A component that renders a preview card for an exhibit within a Leaflet map container. * Includes image and details, with clickable areas for further interaction. - * - * @param {ExhibitCardProps} props - The props for the component. - * @returns {JSX.Element} The rendered JSX for the exhibit preview card. + * @param props - The props for the component. + * @param props.tour - props for tour + * @param props.handleClick - Will handle when user clicks on the exhibit card + * @param props.handleClose - This will close the preview card + * @returns - The rendered JSX for the exhibit preview card. */ function ExhibitPreviewCard({ tour, @@ -36,7 +37,7 @@ function ExhibitPreviewCard({ const [previewImage, setPreviewImage] = useState(tour.image || ''); const [name1, setname1] = useState(tour.category || ''); - const { id, description, coordinates, category } = tour; + const { id, description } = tour; const [width, setWidth] = useState('20.06rem'); const [height, setHeight] = useState('7.687rem'); const isWebDevice = useWebDeviceDetection(); @@ -57,16 +58,6 @@ function ExhibitPreviewCard({ return () => window.removeEventListener('resize', handleResize); }, [handleResize]); - // Map Context - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const map = useMapEvents({ - click: e => { - if (!e.latlng.equals(coordinates as LatLngExpression)) { - handleClose(); - } - }, - }); - // fetch image to use for preview useEffect(() => { const fetchDetails = async () => { @@ -128,6 +119,15 @@ function ExhibitPreviewCard({ e.stopPropagation(); handleClose(); }} + onKeyDown={e => { + if (e.key === 'Enter' || e.key === ' ') { + e.stopPropagation(); + handleClose(); + } + }} + role="button" + tabIndex={0} + aria-label="Close preview" > { + if (e.key === 'Enter' || e.key === ' ') { + e.stopPropagation(); + handleClose(); + } + }} + role="button" + tabIndex={0} + aria-label="Close preview" >
diff --git a/src/supabase/category/queries.ts b/src/supabase/category/queries.ts deleted file mode 100644 index 5dd7978f..00000000 --- a/src/supabase/category/queries.ts +++ /dev/null @@ -1,46 +0,0 @@ -import supabase from '../client'; -import { CategoryRow } from '../../types/types'; -// Assume this function is in `supabase/category/queries.js` -/** - * - * @param category category to retreive color - * @param id - * @returns color for category, else null - */ -// eslint-disable-next-line import/prefer-default-export -export async function getCategoryColor1(id: string | number) { - try { - const { data, error } = await supabase - .from('categories') - .select('color_hex') - .eq('id', id); - - if (error) { - console.error('Error fetching from Supabase:', error.message); - return null; // Return null on query error - } - - // Check if data array is not empty - if (data && data.length > 0 && data[0].color_hex) { - // console.log(`Color for ${category}:`, data[0].color_hex); - return data[0].color_hex; - } - console.log('No matching category found or color_hex is undefined'); - return null; // Return null if no matching data found - } catch (error) { - console.error(`An unexpected error occurred:`, error); - return null; // Return null on unexpected error - } -} - -/** - * Fetches all categories from the database. - * @returns A promise that resolves to an array of ExhibitRow objects. - */ -export async function fetchAllCategories(): Promise { - const { data, error } = await supabase.from('categories').select('*'); - if (error) { - throw new Error(error.message); - } - return data; -} diff --git a/src/supabase/category/queries.tsx b/src/supabase/category/queries.tsx index 94dd2157..d745bec2 100644 --- a/src/supabase/category/queries.tsx +++ b/src/supabase/category/queries.tsx @@ -1,51 +1,30 @@ -'use client'; - -import { CategoryRow } from '../../types/types'; import supabase from '../client'; - -// eslint-disable-next-line jsdoc/require-returns -/** - * - * @param category_in - */ -// eslint-disable-next-line import/prefer-default-export, camelcase -// export async function get_category_color(category_in: string) { -// const { data, error } = await supabase.rpc('get_category_color', { category_in }); -// if (error) { -// // Log the error message for debugging -// console.error(`An error occurred trying to generate color: ${error.message}`); -// // Throw a new error with the message for further handling -// throw new Error(`An error occurred trying to generate color: ${error.message}`); -// } -// return data; -// } +import { CategoryRow } from '../../types/types'; // Assume this function is in `supabase/category/queries.js` /** - * - * @param category - The category for which you want to fetch the color - * @returns The color for the category + * @param id - Each tour or exhibit has its unique identifier + * @returns color for category, else null */ // eslint-disable-next-line import/prefer-default-export -export async function getCategoryColor1(category: string) { +export async function getCategoryColor1(id: string | number) { try { const { data, error } = await supabase - .from('categories') // Adjust according to your actual table name - .select('color') - .eq('category', category); // Use this if you're sure there's only one entry per category + .from('categories') + .select('color_hex') + .eq('id', id); if (error) { - throw new Error(error.message); + return null; // Return null on query error + } + + // Check if data array is not empty + if (data && data.length > 0 && data[0].color_hex) { + return data[0].color_hex; } - // Assuming 'color' is the column you want and each category has a unique color. - // 'data' would be the object containing 'color', so we return data.color. - // Check if 'data' exists to avoid accessing property 'color' of null. - console.log(`Color for ${category}:`, data[0].color); - return data ? data[0].color : null; + return null; // Return null if no matching data found } catch (error) { - console.error(`Error fetching color for category ${category}:`, error); - // Return null or a default color to handle errors gracefully - return null; + return null; // Return null on unexpected error } }