Skip to content

Commit

Permalink
Merge pull request #11 from hypercerts-org/feature/update-hyperboard-…
Browse files Browse the repository at this point in the history
…rendering-to-new-data-structure

Feature/update hyperboard rendering to new data structure
  • Loading branch information
Jipperism authored Nov 3, 2023
2 parents 7a6ba9c + 3f008b3 commit 0a2d643
Show file tree
Hide file tree
Showing 15 changed files with 497 additions and 177 deletions.
33 changes: 33 additions & 0 deletions components/admin/add-hyperboard-registry-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Button, useDisclosure } from "@chakra-ui/react";
import { CreateOrUpdateHyperboardRegistryModal } from "@/components/admin/create-or-update-hyperboard-registry-modal";

export const AddHyperboardRegistryButton = ({
hyperboardId,
registryId,
size,
}: {
hyperboardId: string;
registryId?: string;
size?: string;
}) => {
const { onClose, onOpen, isOpen } = useDisclosure();

return (
<>
<Button
aria-label="Edit hyperboard registry"
colorScheme="blue"
onClick={onOpen}
size={size}
>
Add registry to hyperboard
</Button>
<CreateOrUpdateHyperboardRegistryModal
hyperboardId={hyperboardId}
registryId={registryId}
onClose={onClose}
isOpen={isOpen}
/>
</>
);
};
22 changes: 22 additions & 0 deletions components/admin/create-or-update-hyperboard-registry-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ModalProps } from "@chakra-ui/modal";
import { GenericModal } from "@/components/GenericModal";
import { CreateOrUpdateHyperboardRegistryForm } from "@/components/forms/create-or-update-hyperboard-registry-form";

export const CreateOrUpdateHyperboardRegistryModal = ({
hyperboardId,
registryId,
...modalProps
}: {
registryId?: string;
hyperboardId: string;
} & Omit<ModalProps, "children">) => {
return (
<GenericModal title="Edit hyperboard<>registry connection" {...modalProps}>
<CreateOrUpdateHyperboardRegistryForm
hyperboardId={hyperboardId}
onComplete={modalProps.onClose}
registryId={registryId}
/>
</GenericModal>
);
};
33 changes: 33 additions & 0 deletions components/admin/edit-hyperboard-registry-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { IconButton, useDisclosure } from "@chakra-ui/react";
import { AiFillEdit } from "react-icons/ai";
import { CreateOrUpdateHyperboardRegistryModal } from "@/components/admin/create-or-update-hyperboard-registry-modal";

export const EditHyperboardRegistryButton = ({
hyperboardId,
registryId,
size,
}: {
hyperboardId: string;
registryId?: string;
size?: string;
}) => {
const { onClose, onOpen, isOpen } = useDisclosure();

return (
<>
<IconButton
aria-label="Edit hyperboard registry"
icon={<AiFillEdit />}
colorScheme="blue"
onClick={onOpen}
size={size}
/>
<CreateOrUpdateHyperboardRegistryModal
hyperboardId={hyperboardId}
registryId={registryId}
onClose={onClose}
isOpen={isOpen}
/>
</>
);
};
50 changes: 36 additions & 14 deletions components/admin/hyperboards-admin.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {
Button,
Card,
Center,
Flex,
Heading,
HStack,
Table,
TableContainer,
Tbody,
Expand All @@ -18,6 +20,8 @@ import { useMyHyperboards } from "@/hooks/useMyHyperboards";
import { DeleteHyperboardButton } from "@/components/admin/delete-hyperboard-button";
import { RemoveRegistryFromHyperboardButton } from "@/components/admin/remove-registry-from-hyperboard-button";
import { headerHeight } from "@/components/Layout";
import { EditHyperboardRegistryButton } from "@/components/admin/edit-hyperboard-registry-button";
import { AddHyperboardRegistryButton } from "@/components/admin/add-hyperboard-registry-button";

export const HyperboardsAdmin = () => {
const {
Expand Down Expand Up @@ -49,33 +53,51 @@ export const HyperboardsAdmin = () => {
<Heading>{hyperboard.name}</Heading>
<DeleteHyperboardButton hyperboardId={hyperboard.id} />
</Flex>
{!!hyperboard.registries.length && (
{!!hyperboard.hyperboard_registries.length && (
<TableContainer>
<Table variant={"striped"} size={"sm"} colorScheme="blue">
<Thead>
<Tr>
<Th>Name</Th>
<Td>Label</Td>
<Th>Chain ID</Th>
</Tr>
</Thead>
<Tbody>
{hyperboard.registries.map((registry) => (
<Tr key={registry.id}>
<Td>{registry.name}</Td>
<Td>{registry.chain_id}</Td>
<Td>
<RemoveRegistryFromHyperboardButton
size={"sm"}
hyperboardId={hyperboard.id}
registryId={registry.id}
/>
</Td>
</Tr>
))}
{hyperboard.hyperboard_registries.map(
(hyperboardRegistry) => {
if (!hyperboardRegistry.registries) return null;
const registry = hyperboardRegistry.registries;
return (
<Tr key={registry.id}>
<Td>{registry.name}</Td>
<Td>{hyperboardRegistry.label}</Td>
<Td>{registry.chain_id}</Td>
<Td>
<HStack justifyContent={"end"}>
<EditHyperboardRegistryButton
size={"sm"}
hyperboardId={hyperboard.id}
registryId={registry.id}
/>
<RemoveRegistryFromHyperboardButton
size={"sm"}
hyperboardId={hyperboard.id}
registryId={registry.id}
/>
</HStack>
</Td>
</Tr>
);
},
)}
</Tbody>
</Table>
</TableContainer>
)}
<Center mt={2}>
<AddHyperboardRegistryButton hyperboardId={hyperboard.id} />
</Center>
</Card>
))}
</VStack>
Expand Down
167 changes: 167 additions & 0 deletions components/forms/create-or-update-hyperboard-registry-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { Controller, useForm } from "react-hook-form";
import {
Button,
FormControl,
FormErrorMessage,
FormLabel,
Input,
useToast,
VStack,
} from "@chakra-ui/react";
import { useHypercertClient } from "@/components/providers";
import { SingleRegistrySelector } from "@/components/admin/registry-selector";
import { useFetchRegistryById } from "@/hooks/useFetchRegistryById";
import { useEffect } from "react";
import { useFetchHyperboardRegistryById } from "@/hooks/useFetchHyperboardRegistryById";
import { useGetAuthenticatedClient } from "@/hooks/useGetAuthenticatedClient";
import { useMyHyperboards } from "@/hooks/useMyHyperboards";

export interface CreateOrUpdateHyperboardRegistryFormValues {
label: string;
registry: {
value: string;
label: string;
};
}

export const CreateOrUpdateHyperboardRegistryForm = ({
hyperboardId,
registryId,
initialValues = {},
onComplete,
}: {
hyperboardId: string;
registryId?: string;
initialValues?: Partial<CreateOrUpdateHyperboardRegistryFormValues>;
onComplete?: () => void;
}) => {
const { refetch } = useMyHyperboards();
const { data: registryData } = useFetchRegistryById(registryId);
const { data: hyperboardRegistryData } = useFetchHyperboardRegistryById(
hyperboardId,
registryId,
);

const {
control,
register,
setValue,
formState: { errors, isSubmitting },
handleSubmit,
} = useForm<CreateOrUpdateHyperboardRegistryFormValues>({
reValidateMode: "onBlur",
defaultValues: initialValues,
});

useEffect(() => {
if (registryData?.data) {
setValue("registry", {
value: registryData.data.id,
label: registryData.data.name,
});
}
}, [registryData?.data, setValue]);

useEffect(() => {
if (hyperboardRegistryData?.data?.label) {
setValue("label", hyperboardRegistryData.data.label);
}
}, [hyperboardRegistryData?.data, setValue]);

const toast = useToast();
const client = useHypercertClient();

const getClient = useGetAuthenticatedClient();
const isEdit = !!registryId;

const onSubmit = async (
values: CreateOrUpdateHyperboardRegistryFormValues,
) => {
const supabase = await getClient();

if (!client) {
toast({
title: "Client is not initialized",
status: "error",
});
return;
}

if (!supabase) {
toast({
title: "Supabase is not initialized",
status: "error",
});
return;
}

if (!hyperboardId) {
toast({
title: "Hyperboard ID is required",
status: "error",
});
return;
}

const upsertValue = {
label: values.label,
registry_id: values.registry.value,
hyperboard_id: hyperboardId,
};

try {
await supabase.from("hyperboard_registries").upsert(upsertValue);
} catch (e) {
console.error(e);
toast({
title: "Error",
description: "Could not create or update hyperboard registry",
status: "error",
duration: 9000,
isClosable: true,
});
return;
}

await refetch();
onComplete?.();
};

return (
<form onSubmit={handleSubmit(onSubmit)}>
<VStack>
<FormControl isInvalid={!!errors.registry}>
<FormLabel>Registry ID</FormLabel>
<Controller
control={control}
render={(props) => (
<SingleRegistrySelector
isDisabled={isEdit || isSubmitting}
{...props.field}
/>
)}
name={"registry"}
/>
<FormErrorMessage>{errors.registry?.message}</FormErrorMessage>
</FormControl>
<FormControl isInvalid={!!errors.label}>
<FormLabel>Label</FormLabel>
<Input
disabled={isSubmitting}
{...register("label", {
required: "This is required",
minLength: {
value: 4,
message: "Minimum length should be 4",
},
})}
/>
<FormErrorMessage>{errors.label?.message}</FormErrorMessage>
</FormControl>
<Button mt={4} colorScheme="teal" type="submit">
Submit
</Button>
</VStack>
</form>
);
};
Loading

0 comments on commit 0a2d643

Please sign in to comment.