mirror of
https://github.com/geoffsee/open-gsio.git
synced 2025-09-08 22:56:46 +00:00
init
This commit is contained in:
29
src/components/toolbar/GithubButton.tsx
Normal file
29
src/components/toolbar/GithubButton.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import React from "react";
|
||||
import { IconButton } from "@chakra-ui/react";
|
||||
import { Github } from "lucide-react";
|
||||
import { toolbarButtonZIndex } from "./Toolbar";
|
||||
|
||||
export default function GithubButton() {
|
||||
return (
|
||||
<IconButton
|
||||
as="a"
|
||||
href="https://github.com/geoffsee"
|
||||
target="_blank"
|
||||
aria-label="GitHub"
|
||||
icon={<Github />}
|
||||
size="md"
|
||||
bg="transparent"
|
||||
stroke="text.accent"
|
||||
color="text.accent"
|
||||
_hover={{
|
||||
bg: "transparent",
|
||||
svg: {
|
||||
stroke: "accent.secondary",
|
||||
transition: "stroke 0.3s ease-in-out",
|
||||
},
|
||||
}}
|
||||
title="GitHub"
|
||||
zIndex={toolbarButtonZIndex}
|
||||
/>
|
||||
);
|
||||
}
|
41
src/components/toolbar/SupportThisSiteButton.tsx
Normal file
41
src/components/toolbar/SupportThisSiteButton.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import React from "react";
|
||||
import { IconButton, useDisclosure } from "@chakra-ui/react";
|
||||
import { LucideHeart } from "lucide-react";
|
||||
import { toolbarButtonZIndex } from "./Toolbar";
|
||||
import SupportThisSiteModal from "./SupportThisSiteModal";
|
||||
|
||||
export default function SupportThisSiteButton() {
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
return (
|
||||
<>
|
||||
<IconButton
|
||||
as="a"
|
||||
aria-label="Support"
|
||||
icon={<LucideHeart />}
|
||||
cursor="pointer"
|
||||
onClick={onOpen}
|
||||
size="md"
|
||||
stroke="text.accent"
|
||||
bg="transparent"
|
||||
_hover={{
|
||||
bg: "transparent",
|
||||
svg: {
|
||||
stroke: "accent.danger",
|
||||
transition: "stroke 0.3s ease-in-out",
|
||||
},
|
||||
}}
|
||||
title="Support"
|
||||
variant="ghost"
|
||||
zIndex={toolbarButtonZIndex}
|
||||
sx={{
|
||||
svg: {
|
||||
stroke: "text.accent",
|
||||
strokeWidth: "2px",
|
||||
transition: "stroke 0.2s ease-in-out",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<SupportThisSiteModal isOpen={isOpen} onClose={onClose} />
|
||||
</>
|
||||
);
|
||||
}
|
225
src/components/toolbar/SupportThisSiteModal.tsx
Normal file
225
src/components/toolbar/SupportThisSiteModal.tsx
Normal file
@@ -0,0 +1,225 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Input,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
ModalContent,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
Tab,
|
||||
TabList,
|
||||
TabPanel,
|
||||
TabPanels,
|
||||
Tabs,
|
||||
Text,
|
||||
useClipboard,
|
||||
useToast,
|
||||
VStack,
|
||||
} from "@chakra-ui/react";
|
||||
import { QRCodeCanvas } from "qrcode.react";
|
||||
import { FaBitcoin, FaEthereum } from "react-icons/fa";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import clientTransactionStore from "../../stores/ClientTransactionStore";
|
||||
import DogecoinIcon from "../icons/DogecoinIcon";
|
||||
|
||||
const SupportThisSiteModal = observer(({ isOpen, onClose, zIndex }) => {
|
||||
const { hasCopied, onCopy } = useClipboard(
|
||||
clientTransactionStore.depositAddress || "",
|
||||
);
|
||||
const toast = useToast();
|
||||
|
||||
const handleCopy = () => {
|
||||
if (clientTransactionStore.depositAddress) {
|
||||
onCopy();
|
||||
toast({
|
||||
title: "Address Copied!",
|
||||
description: "Thank you for your support!",
|
||||
status: "success",
|
||||
duration: 3000,
|
||||
isClosable: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleConfirmAmount = async () => {
|
||||
try {
|
||||
await clientTransactionStore.prepareTransaction();
|
||||
toast({
|
||||
title: "Success",
|
||||
description: `Use your wallet app (Coinbase, ...ect) to send the selected asset to the provided address.`,
|
||||
status: "success",
|
||||
duration: 6000,
|
||||
isClosable: true,
|
||||
});
|
||||
} catch (error) {
|
||||
toast({
|
||||
title: "Transaction Failed",
|
||||
description: "There was an issue preparing your transaction.",
|
||||
status: "error",
|
||||
duration: 3000,
|
||||
isClosable: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const donationMethods = [
|
||||
{
|
||||
name: "Ethereum",
|
||||
icon: FaEthereum,
|
||||
},
|
||||
{
|
||||
name: "Bitcoin",
|
||||
icon: FaBitcoin,
|
||||
},
|
||||
{
|
||||
name: "Dogecoin",
|
||||
icon: DogecoinIcon,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
size="md"
|
||||
motionPreset="slideInBottom"
|
||||
zIndex={zIndex}
|
||||
>
|
||||
<ModalOverlay />
|
||||
<ModalContent bg="gray.800" color="text.primary">
|
||||
<ModalHeader textAlign="center" mb={2}>
|
||||
Support
|
||||
</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
<VStack spacing={8} align="center">
|
||||
<Text fontSize="md" textAlign="center">
|
||||
Your contributions are fuel for magic.
|
||||
</Text>
|
||||
<Tabs
|
||||
align="center"
|
||||
variant="soft-rounded"
|
||||
colorScheme="teal"
|
||||
isFitted
|
||||
>
|
||||
<TabList mb={2} w={"20%"}>
|
||||
{donationMethods.map((method) => (
|
||||
<Tab
|
||||
p={4}
|
||||
key={method.name}
|
||||
onClick={() => {
|
||||
clientTransactionStore.setSelectedMethod(method.name);
|
||||
}}
|
||||
>
|
||||
<Box p={1} w={"fit-content"}>
|
||||
<method.icon />{" "}
|
||||
</Box>
|
||||
{method.name}
|
||||
</Tab>
|
||||
))}
|
||||
</TabList>
|
||||
<TabPanels>
|
||||
{donationMethods.map((method) => (
|
||||
<TabPanel key={method.name}>
|
||||
{!clientTransactionStore.userConfirmed ? (
|
||||
<VStack spacing={4}>
|
||||
<Text>Enter your information:</Text>
|
||||
<Input
|
||||
placeholder="Your name"
|
||||
value={
|
||||
clientTransactionStore.donerId as string | undefined
|
||||
}
|
||||
onChange={(e) =>
|
||||
clientTransactionStore.setDonerId(e.target.value)
|
||||
}
|
||||
type="text"
|
||||
bg="gray.700"
|
||||
color="white"
|
||||
w="100%"
|
||||
/>
|
||||
<Text>Enter the amount you wish to donate:</Text>
|
||||
<Input
|
||||
placeholder="Enter amount"
|
||||
value={
|
||||
clientTransactionStore.amount as number | undefined
|
||||
}
|
||||
onChange={(e) =>
|
||||
clientTransactionStore.setAmount(e.target.value)
|
||||
}
|
||||
type="number"
|
||||
bg="gray.700"
|
||||
color="white"
|
||||
w="100%"
|
||||
/>
|
||||
<Button
|
||||
onClick={handleConfirmAmount}
|
||||
size="md"
|
||||
colorScheme="teal"
|
||||
>
|
||||
Confirm Amount
|
||||
</Button>
|
||||
</VStack>
|
||||
) : (
|
||||
<>
|
||||
<Box
|
||||
bg="white"
|
||||
p={2}
|
||||
borderRadius="lg"
|
||||
mb={4}
|
||||
w={"min-content"}
|
||||
>
|
||||
<QRCodeCanvas
|
||||
value={
|
||||
clientTransactionStore.depositAddress as string
|
||||
}
|
||||
size={180}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
bg="gray.700"
|
||||
p={4}
|
||||
borderRadius="md"
|
||||
wordBreak="unset"
|
||||
w="100%"
|
||||
textAlign="center"
|
||||
mb={4}
|
||||
>
|
||||
<Text fontWeight="bold" fontSize="xs">
|
||||
{clientTransactionStore.depositAddress}
|
||||
</Text>
|
||||
</Box>
|
||||
<Button
|
||||
onClick={handleCopy}
|
||||
size="md"
|
||||
colorScheme="teal"
|
||||
mb={4}
|
||||
>
|
||||
{hasCopied ? "Address Copied!" : "Copy Address"}
|
||||
</Button>
|
||||
<Text fontSize="md" fontWeight="bold">
|
||||
Transaction ID: {clientTransactionStore.txId}
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
</TabPanel>
|
||||
))}
|
||||
</TabPanels>
|
||||
</Tabs>
|
||||
</VStack>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button variant="outline" mr={3} onClick={onClose} colorScheme="gray">
|
||||
Close
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
});
|
||||
|
||||
export default SupportThisSiteModal;
|
25
src/components/toolbar/Toolbar.tsx
Normal file
25
src/components/toolbar/Toolbar.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from "react";
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import SupportThisSiteButton from "./SupportThisSiteButton";
|
||||
import GithubButton from "./GithubButton";
|
||||
import BuiltWithButton from "../BuiltWithButton";
|
||||
|
||||
const toolbarButtonZIndex = 901;
|
||||
|
||||
export { toolbarButtonZIndex };
|
||||
|
||||
function ToolBar({ isMobile }) {
|
||||
return (
|
||||
<Flex
|
||||
direction={isMobile ? "row" : "column"}
|
||||
alignItems={isMobile ? "flex-start" : "flex-end"}
|
||||
pb={4}
|
||||
>
|
||||
<SupportThisSiteButton />
|
||||
<GithubButton />
|
||||
<BuiltWithButton />
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
export default ToolBar;
|
Reference in New Issue
Block a user