74 lines
2.6 KiB
TypeScript
74 lines
2.6 KiB
TypeScript
import { Check, Copy, RefreshCw } from "lucide-react";
|
|
import React from "react";
|
|
import { useOrigin } from "~/hooks/use-origin";
|
|
import { ModalType, useModalStore } from "~/stores/modal-store";
|
|
import { Button } from "../ui/button";
|
|
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "../ui/dialog";
|
|
import { Input } from "../ui/input";
|
|
import { Label } from "../ui/label";
|
|
|
|
export default function CreateServerInviteModal() {
|
|
const { type, data, isOpen, onClose } = useModalStore();
|
|
const [inviteCode, setInviteCode] = React.useState<string | undefined>(undefined);
|
|
const origin = useOrigin();
|
|
const [isCopied, setCopied] = React.useState(false);
|
|
|
|
const isModalOpen = type === ModalType.CREATE_SERVER_INVITE && isOpen;
|
|
const inviteLink = `${origin}/app/invite/${inviteCode}`;
|
|
|
|
const onOpenChange = () => {
|
|
onClose();
|
|
};
|
|
|
|
const regenerateInviteCode = () => {
|
|
import("~/lib/api/client/server")
|
|
.then((m) => m.default.createInvite((data as { serverId: string }).serverId))
|
|
.then((invite) => {
|
|
setInviteCode(invite.code);
|
|
});
|
|
};
|
|
|
|
const onCopy = () => {
|
|
navigator.clipboard.writeText(inviteLink);
|
|
setCopied(true);
|
|
|
|
setTimeout(() => setCopied(false), 1000);
|
|
};
|
|
|
|
React.useEffect(() => {
|
|
if (isModalOpen) {
|
|
import("~/lib/api/client/server")
|
|
.then((m) => m.default.createInvite((data as { serverId: string }).serverId))
|
|
.then((invite) => {
|
|
setInviteCode(invite.code);
|
|
});
|
|
} else {
|
|
setInviteCode(undefined);
|
|
}
|
|
}, [isModalOpen]);
|
|
|
|
return (
|
|
<Dialog open={isModalOpen} onOpenChange={onOpenChange}>
|
|
<DialogContent className="sm:max-w-md">
|
|
<DialogHeader>
|
|
<DialogTitle>Invite your friends</DialogTitle>
|
|
</DialogHeader>
|
|
|
|
<Label>Server invite link</Label>
|
|
<div className="flex items-center gap-x-2">
|
|
<Input value={inviteLink} readOnly />
|
|
<Button variant="ghost" size="icon" onClick={onCopy}>
|
|
{isCopied ? <Check className="size-4" /> : <Copy className="size-4" />}
|
|
</Button>
|
|
</div>
|
|
<DialogFooter>
|
|
<Button variant="link" size="none" className="h-9 py-2" onClick={regenerateInviteCode}>
|
|
Generate a new invite
|
|
<RefreshCw />
|
|
</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|