Skip to content

Commit

Permalink
Merge pull request #8 from hypercerts-org/feature/blueprints
Browse files Browse the repository at this point in the history
Feature/blueprints
  • Loading branch information
Jipperism authored Oct 27, 2023
2 parents fc2e231 + e81b090 commit c96900b
Show file tree
Hide file tree
Showing 30 changed files with 1,590 additions and 22 deletions.
14 changes: 14 additions & 0 deletions components/admin/blueprints-admin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Card, Flex, VStack } from "@chakra-ui/react";
import { CreateOrUpdateBlueprintForm } from "@/components/forms/create-or-update-blueprint-form";

export const BlueprintsAdmin = () => {
return (
<Flex direction={"column"} width={"100%"}>
<VStack minHeight={"100%"} spacing={4} alignItems={"flex-start"}>
<Card p={4}>
<CreateOrUpdateBlueprintForm />
</Card>
</VStack>
</Flex>
);
};
17 changes: 17 additions & 0 deletions components/admin/create-blueprint-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ModalProps } from "@chakra-ui/modal";
import { GenericModal } from "@/components/GenericModal";
import { CreateOrUpdateBlueprintForm } from "@/components/forms/create-or-update-blueprint-form";

export const CreateBlueprintModal = ({
registryId,
...modalProps
}: { registryId?: string } & Omit<ModalProps, "children">) => {
return (
<GenericModal title="Create Blueprint" {...modalProps}>
<CreateOrUpdateBlueprintForm
onComplete={modalProps.onClose}
registryId={registryId}
/>
</GenericModal>
);
};
51 changes: 37 additions & 14 deletions components/admin/create-registry-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
CreateUpdateRegistryFormValues,
} from "@/components/forms/create-or-update-registry-form";
import { useChainId } from "wagmi";
import { useCreateClaims } from "@/hooks/useCreateClaims";
import { useHypercertClient } from "@/components/providers";

export const CreateRegistryModal = ({
initialValues,
Expand All @@ -21,13 +23,26 @@ export const CreateRegistryModal = ({
const address = useAddress();
const toast = useToast();
const chainId = useChainId();
const client = useHypercertClient();

const { refetch } = useMyRegistries();
const { mutateAsync: createClaims } = useCreateClaims();

const onConfirm = async ({
claims,
...registry
}: CreateUpdateRegistryFormValues) => {
if (!client) {
toast({
title: "Error",
description: "Client not initialized",
status: "error",
duration: 9000,
isClosable: true,
});
return;
}

if (!address) {
toast({
title: "Error",
Expand Down Expand Up @@ -83,22 +98,30 @@ export const CreateRegistryModal = ({
status: "success",
});

const claimInserts: ClaimInsert[] = claims.map(({ hypercert_id }) => ({
registry_id: insertedRegistry.id,
hypercert_id,
chain_id: chainId,
admin_id: address,
}));

const { error: insertClaimsError } = await supabase
.from("claims")
.insert(claimInserts)
.select();

if (insertClaimsError) {
try {
const claimInserts: ClaimInsert[] = await Promise.all(
claims.map(async ({ hypercert_id }) => {
const claim = await client.indexer.claimById(hypercert_id);
if (!claim.claim) {
throw new Error("Claim not found");
}
return {
registry_id: insertedRegistry.id,
hypercert_id,
chain_id: chainId,
admin_id: address,
owner_id: claim.claim.owner,
};
}),
);
await createClaims({
claims: claimInserts,
});
} catch (insertClaimsError) {
console.error(insertClaimsError);
toast({
title: "Error",
description: insertClaimsError.message,
description: "Something went wrong with creating claims",
status: "error",
duration: 9000,
isClosable: true,
Expand Down
59 changes: 59 additions & 0 deletions components/admin/delete-blueprint-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { IconButton, useDisclosure, useToast } from "@chakra-ui/react";
import { useMyRegistries } from "@/hooks/useMyRegistries";
import { AiFillDelete } from "react-icons/ai";
import { AlertDialog } from "@/components/dialogs/alert-confirmation-dialog";
import { useDeleteBlueprint } from "@/hooks/useDeleteBlueprint";

export const DeleteBlueprintButton = ({
blueprintId,
size = "sm",
}: {
blueprintId: number;
size?: string;
}) => {
const { refetch } = useMyRegistries();
const { onClose, onOpen, isOpen } = useDisclosure();

const toast = useToast();
const { mutateAsync: deleteBlueprintAsync } = useDeleteBlueprint();

const onDeleteBlueprint = async () => {
try {
await deleteBlueprintAsync(blueprintId);
} catch (e) {
console.error(e);
toast({
title: "Error",
description: "Could not delete blueprint",
status: "error",
duration: 9000,
isClosable: true,
});
}

await refetch();
toast({
title: "Success",
description: "Blueprint deleted",
status: "success",
});
};

return (
<>
<IconButton
size={size}
aria-label="Delete blueprint"
icon={<AiFillDelete />}
colorScheme="red"
onClick={onOpen}
/>
<AlertDialog
title="Delete Blueprint"
onConfirm={() => onDeleteBlueprint()}
onClose={onClose}
isOpen={isOpen}
/>
</>
);
};
87 changes: 87 additions & 0 deletions components/admin/my-blueprints-admin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import {
Card,
Flex,
Spinner,
Table,
TableContainer,
Tbody,
Td,
Th,
Thead,
Tr,
VStack,
} from "@chakra-ui/react";
import { useMyBlueprints } from "@/hooks/useMyBlueprints";
import { formatAddress } from "@/utils/formatting";
import Link from "next/link";
import { useRouter } from "next/router";
import { BlueprintMinter } from "@/components/minting/blueprint-minter";

export const MyBlueprintsAdmin = () => {
const { data, isLoading } = useMyBlueprints();
const { query, push } = useRouter();

if (isLoading) {
return <Spinner />;
}

if (!data) {
return null;
}

const blueprintId = query["blueprintId"];
const parsedBluePrintId = parseInt(blueprintId as string);

return (
<Flex direction={"column"} width={"100%"}>
<VStack minHeight={"100%"} spacing={4} alignItems={"flex-start"}>
<Card p={4} w={"100%"}>
{blueprintId ? (
<BlueprintMinter
blueprintId={parsedBluePrintId}
onComplete={() => push("/admin/my-claims/")}
/>
) : (
<TableContainer width={"100%"} height={"100%"}>
<Table variant={"striped"} colorScheme="blue" size={"sm"}>
<Thead>
<Tr>
<Th>Name</Th>
<Th>Registry</Th>
<Th>Created on</Th>
<Th>Created by</Th>
</Tr>
</Thead>
<Tbody>
{data.data?.map((blueprint) => (
<Tr key={blueprint.id}>
{/*
// @ts-ignore */}
<Td>{blueprint.form_values?.name}</Td>
<Td>{blueprint.registries?.name}</Td>
<Td>{new Date(blueprint.created_at).toLocaleString()}</Td>
<Td>{formatAddress(blueprint.admin_id)}</Td>
<Td textDecoration={"underline"}>
<Link
href={{
href: "/admin/blueprints",
pathname: "/admin/my-blueprints",
query: {
blueprintId: blueprint.id,
},
}}
>
Mint
</Link>{" "}
</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
)}
</Card>
</VStack>
</Flex>
);
};
59 changes: 59 additions & 0 deletions components/admin/my-claims-admin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import {
Card,
Flex,
Heading,
TableContainer,
Tr,
Table,
VStack,
Thead,
Tbody,
Th,
Center,
Spinner,
} from "@chakra-ui/react";
import { useMyClaims } from "@/hooks/useMyClaims";
import { ClaimRow } from "@/components/admin/registries-admin";

export const MyClaimsAdmin = () => {
const { data, isLoading } = useMyClaims();

if (isLoading) {
return <Spinner />;
}

const myClaims = data?.data;

return (
<Flex direction={"column"} width={"100%"}>
<VStack minHeight={"100%"} spacing={4} alignItems={"flex-start"}>
<Card width={"100%"}>
{myClaims?.length ? (
<TableContainer width={"100%"}>
<Table variant={"striped"} colorScheme="blue" size={"sm"}>
<Thead>
<Tr>
<Th>Name</Th>
<Th>Chain</Th>
<Th>Admin</Th>
<Th>External url</Th>
<Th>Description</Th>
</Tr>
</Thead>
<Tbody>
{myClaims.map((claim) => (
<ClaimRow key={claim.id} {...claim} />
))}
</Tbody>
</Table>
</TableContainer>
) : (
<Center p={4}>
<Heading>No claims found</Heading>
</Center>
)}
</Card>
</VStack>
</Flex>
);
};
Loading

0 comments on commit c96900b

Please sign in to comment.