Skip to content

Commit

Permalink
Merge pull request #1 from Kiel-H-Byrne/addListingCard
Browse files Browse the repository at this point in the history
Add listing card
  • Loading branch information
Kiel-H-Byrne authored Oct 13, 2023
2 parents 2226a63 + 67ecd9b commit 4251864
Show file tree
Hide file tree
Showing 15 changed files with 350 additions and 80 deletions.
9 changes: 2 additions & 7 deletions components/AddListingForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,7 @@ const AddListingForm = ({ onDrawerClose }: { onDrawerClose: () => void }) => {
);

useEffect(() => {
if (Object.keys(errors).length !== 0) {
console.log(errors);
}
}, [errors]);

useEffect(() => {
isSubmitting && submitToast();
isSubmitting && Object.keys(errors).length !==0 && submitToast();
if (isSubmitSuccessful) {
reset();
onDrawerClose();
Expand All @@ -118,6 +112,7 @@ const AddListingForm = ({ onDrawerClose }: { onDrawerClose: () => void }) => {
reset,
onDrawerClose,
successToast,
errors
]);

return (
Expand Down
21 changes: 21 additions & 0 deletions components/AppList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { IListing } from "@/types";
import fetcher from "@/util/fetch";
import { HStack } from '@chakra-ui/react';
import SWR from "swr";
import BusinessCard from "./ListingCard2";
const AppList = () => {
const data_uri = "api/listings";
const { data: fetchData, error } = SWR(data_uri, fetcher, {
loadingTimeout: 1000,
errorRetryCount: 2,
});
return (
<HStack flexWrap={'wrap'}>
{fetchData && fetchData.map((listing: IListing) =>
<BusinessCard activeListing={listing} key={listing.name} />
)}
</HStack>
);
};

export default AppList;
52 changes: 35 additions & 17 deletions components/AppMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import {
DrawerHeader,
DrawerOverlay,
Flex,
Heading,
Icon,
Progress,
Tab,
TabList,
TabPanel,
TabPanels,
Tabs,
Text,
createStandaloneToast,
useDisclosure,
useToast,
} from "@chakra-ui/react";
import {
GoogleMap,
Expand All @@ -36,6 +36,7 @@ import SWR from "swr";
import { GLocation, IAppMap, IListing } from "../types";
import { CLUSTER_STYLE, GEOCENTER, MAP_STYLES } from "../util/constants";
import { MyInfoWindow, MyMarker } from "./";
import ListingCard from "./ListingCard";

export const default_props = {
center: GEOCENTER,
Expand Down Expand Up @@ -72,7 +73,7 @@ export const default_props = {
},
};

const AppMap = ({ client_location, setMapInstance, mapInstance }: IAppMap) => {
const AppMap = ({ client_location, setMapInstance }: IAppMap) => {
let { center, zoom, options } = default_props;
const uri = client_location
? `api/listings?lat=${client_location.lat}&lng=${client_location.lng}`
Expand Down Expand Up @@ -104,7 +105,7 @@ const AppMap = ({ client_location, setMapInstance, mapInstance }: IAppMap) => {
errorRetryCount: 2,
});

const toast = useToast();
const { ToastContainer, toast } = createStandaloneToast();

const useRenderMarkers: (clusterer: Clusterer) => React.ReactElement =
useCallback(
Expand Down Expand Up @@ -180,7 +181,18 @@ const AppMap = ({ client_location, setMapInstance, mapInstance }: IAppMap) => {
const handleClickCluster = useCallback(() => {
setWindowClosed();
}, [setWindowClosed]);
return isLoaded ? (
const searchToastData = {
title: "Searching Area...",
status: "loading" as any,
id: "searching-toast",
};
const noResultsToastData = {
title: "No Results",
status: "info" as any,
id: "noresults-toast",
};

return isLoaded ? (
<GoogleMap
onLoad={(map) => {
// const bounds = new window.google.maps.LatLngBounds();
Expand Down Expand Up @@ -208,11 +220,9 @@ const AppMap = ({ client_location, setMapInstance, mapInstance }: IAppMap) => {
setSelectedCategories={setSelectedCategories}
/>
)} */}
{!fetchData && toast({ title: "Searching Area...", status: "info" })}
{fetchData &&
fetchData.length == 0 &&
toast({ title: "No Results", status: "info" })}
{fetchData && fetchData.length !== 0 && (
{/* <ToastContainer /> */}
{/* {!fetchData && toast(searchToastData)} */}
{fetchData && fetchData.length !== 0 ? (
<MarkerClusterer
styles={CLUSTER_STYLE}
averageCenter
Expand All @@ -225,10 +235,13 @@ const AppMap = ({ client_location, setMapInstance, mapInstance }: IAppMap) => {
>
{useRenderMarkers}
</MarkerClusterer>
)}
) : null}

{activeData && isWindowOpen && (
<MyInfoWindow activeData={activeData} position={{lat: activeData[0]?.lat!, lng: activeData[0]?.lng!}} />
<MyInfoWindow
activeData={activeData}
position={{ lat: activeData[0]?.lat!, lng: activeData[0]?.lng! }}
/>
)}

{activeData && isDrawerOpen && (
Expand All @@ -242,7 +255,11 @@ const AppMap = ({ client_location, setMapInstance, mapInstance }: IAppMap) => {
<DrawerOverlay />
<DrawerContent>
<DrawerCloseButton />
<DrawerHeader bgColor={"gray.200"} pl={1} display={'flex'}> <Icon boxSize={7} mx={2} as={MdInfoOutline} />Listing Information</DrawerHeader>
<DrawerHeader bgColor={"gray.200"} pl={1} display={"flex"}>
{" "}
<Icon boxSize={7} mx={2} as={MdInfoOutline} />
Listing Information
</DrawerHeader>
<DrawerBody p={0}>
{activeData.length > 1 ? (
<Tabs isFitted variant="enclosed">
Expand Down Expand Up @@ -287,8 +304,7 @@ const AppMap = ({ client_location, setMapInstance, mapInstance }: IAppMap) => {
</Tabs>
) : (
<Box px={3}>
<Heading>{activeData[0].name}</Heading>

<ListingCard activeListing={activeData[0]} />
</Box>
)}
</DrawerBody>
Expand All @@ -298,7 +314,9 @@ const AppMap = ({ client_location, setMapInstance, mapInstance }: IAppMap) => {

{/* <HeatmapLayer map={this.state.map && this.state.map} data={data.map(x => {x.location})} /> */}
</GoogleMap>
) : null;
) : (
<Progress />
);
};

export default memo(AppMap);
6 changes: 3 additions & 3 deletions components/CustomHead.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ const CustomHead = ({ title }: Props) => {
name="msapplication-TileImage"
content="/img/icons/mstile-144x144.png"
/>
<link
{/* <link
rel="manifest"
type="application/manifest+json"
href="/app_manifest.json"
/>
/> */}

<link
rel="icon"
Expand All @@ -97,4 +97,4 @@ const CustomHead = ({ title }: Props) => {
</Head>
);
};
export default memo(CustomHead)
export default memo(CustomHead);
66 changes: 66 additions & 0 deletions components/ListingCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { IClaims, IListing } from "@/types";
import { Box, Button, Collapse, Heading, Image, Text } from "@chakra-ui/react";
import { useState } from "react";

const ListingCard = ({ activeListing }: { activeListing: IListing }) => {
const [isOpen, setIsOpen] = useState(false);
const toggleCollapse = () => {
setIsOpen(!isOpen);
};

const { name, address, description, claims, imageUri } = activeListing;
const getLikelyOwnerInfo = (claims: IClaims) => claims[0];
const ownerInfo = claims && getLikelyOwnerInfo(claims);
return (
<Box
borderWidth="1px"
borderRadius="lg"
overflow="hidden"
boxShadow="lg"
p={4}
maxW="400px"
>
<Box position="relative">
<Image src={imageUri} alt={name} h="200px" w="100%" objectFit="cover" />
<Box
position="absolute"
bottom="0"
left="0"
right="0"
bg="rgba(0, 0, 0, 0.6)"
color="white"
p={4}
>
<Text fontSize="sm">{address}</Text>
<Heading fontSize="2xl" mt={2}>
{name}
</Heading>
<Text fontSize="md" mt={2}>
{description}
</Text>
<Box mt={4}>
<Button size="sm" variant="ghost" onClick={toggleCollapse}>
Owned by {ownerInfo?.member.name}
</Button>
<Collapse in={isOpen} animateOpacity>
<Box mt={2} p={2} bg="gray.100">
{/* Additional owner information */}
</Box>
</Collapse>
</Box>
</Box>
</Box>
<Box mt={4}>
<Button colorScheme="blue" size="sm" mr={2}>
Get Directions
</Button>
<Button colorScheme="blue" size="sm">
Share
</Button>
{/* Additional CTA buttons */}
</Box>
</Box>
);
};

export default ListingCard;
114 changes: 114 additions & 0 deletions components/ListingCard2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { IListing, PHA_LODGES } from "@/types";
import { ChevronDownIcon, ChevronUpIcon } from "@chakra-ui/icons";
import {
Box,
Button,
Collapse,
Flex,
IconButton,
Image,
Text,
} from "@chakra-ui/react";
import { useState } from "react";
import { MdDirections, MdShare } from "react-icons/md";

const getLodgeName = ({
state,
lodgeNo,
}: {
state: string | undefined;
lodgeNo: number | undefined;
//@ts-ignore
}) => state && lodgeNo && (PHA_LODGES[state] as any[lodgeNo]);

const BusinessCard = ({ activeListing }: { activeListing: IListing }) => {
const [isOwnerInfoOpen, setIsOwnerInfoOpen] = useState(false);
const { claims, imageUri, creator } = activeListing;
const owner = claims?.[0].member || creator;

const handleOwnerInfoToggle = () => {
setIsOwnerInfoOpen(!isOwnerInfoOpen);
};

return (
<Box
maxW="md"
mx="auto"
borderWidth="1px"
borderRadius="lg"
overflow="hidden"
boxShadow="md"
>
{/* Image section */}
<Image src={imageUri} alt="Business Image" />

{/* Business Information */}
<Box p="4">
<Text fontWeight="bold" fontSize="lg">
{activeListing.name}
</Text>
<Text fontSize="sm" color="gray.600">
{owner?.name}
</Text>
<Text fontSize="sm" color="gray.600">
{activeListing.address}
</Text>

{/* Owner Information Dropdown */}
<Flex justify="space-between" align="center" mt="2">
<Button size="sm" colorScheme="teal" onClick={handleOwnerInfoToggle}>
Owned by {owner?.name}
</Button>

<IconButton
icon={isOwnerInfoOpen ? <ChevronUpIcon /> : <ChevronDownIcon />}
aria-label="Toggle Owner Info"
variant="outline"
size="sm"
onClick={handleOwnerInfoToggle}
/>
</Flex>

<Collapse in={isOwnerInfoOpen} animateOpacity>
<Box p="4" mt="2" bg="gray.100" rounded="md">
<Text fontSize="sm" fontWeight="bold">
Owner Information
</Text>
<Text fontSize="sm">{owner?.name}</Text>
<Text fontSize="sm">
{getLodgeName({
state: owner?.profile.lodgeState,
lodgeNo: owner?.profile.lodgeNumber,
})}
</Text>
</Box>
</Collapse>

{/* Call to Action Buttons */}
<Flex justify="space-between" align="center" mt="4">
<Button
leftIcon={<MdDirections />}
colorScheme="blue"
size="sm"
rounded="full"
// onClick={directions}
>
Get Directions
</Button>

<Button
leftIcon={<MdShare />}
colorScheme="teal"
size="sm"
rounded="full"
// onClick={share}
>
Share Business
</Button>
</Flex>
</Box>
</Box>
);
};

export default BusinessCard;
4 changes: 2 additions & 2 deletions components/ListingInfoWindow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Progress } from "@chakra-ui/react";
import { InfoWindow } from "@react-google-maps/api";
import React from "react";
import { IListing } from "../types";
import { CondensedCard } from "./";
import ListingCard from "./ListingCard2";

const ListingInfoWindow = ({ activeListing }: {activeListing: IListing}) => {
const { lat,lng } = activeListing;
Expand All @@ -18,7 +18,7 @@ const ListingInfoWindow = ({ activeListing }: {activeListing: IListing}) => {
>
{activeListing ? (
<div /*className={style.root}*/>
<CondensedCard activeListing={activeListing} />
<ListingCard activeListing={activeListing} />
</div>
) : <Progress />}
</InfoWindow>
Expand Down
Loading

0 comments on commit 4251864

Please sign in to comment.