import copy from "copy-to-clipboard"; import React, { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { Textarea } from "@/components/ui/textarea"; import { userServiceClient } from "@/connect"; import useCurrentUser from "@/hooks/useCurrentUser"; import useLoading from "@/hooks/useLoading"; import { handleError } from "@/lib/error"; import { CreatePersonalAccessTokenResponse } from "@/types/proto/api/v1/user_service_pb"; import { useTranslate } from "@/utils/i18n"; interface Props { open: boolean; onOpenChange: (open: boolean) => void; onSuccess: (response: CreatePersonalAccessTokenResponse) => void; } interface State { description: string; expiration: number; } function CreateAccessTokenDialog({ open, onOpenChange, onSuccess }: Props) { const t = useTranslate(); const currentUser = useCurrentUser(); const [state, setState] = useState({ description: "", expiration: 30, // Default: 30 days }); const [createdToken, setCreatedToken] = useState(null); const requestState = useLoading(false); // Expiration options in days (0 = never expires) const expirationOptions = [ { label: t("setting.access-token.create-dialog.duration-1m"), value: 30, }, { label: "90 Days", value: 90, }, { label: t("setting.access-token.create-dialog.duration-never"), value: 0, }, ]; const setPartialState = (partialState: Partial) => { setState({ ...state, ...partialState, }); }; const handleDescriptionInputChange = (e: React.ChangeEvent) => { setPartialState({ description: e.target.value, }); }; const handleRoleInputChange = (value: string) => { setPartialState({ expiration: Number(value), }); }; const handleSaveBtnClick = async () => { if (!state.description) { toast.error(t("message.description-is-required")); return; } try { requestState.setLoading(); const response = await userServiceClient.createPersonalAccessToken({ parent: currentUser?.name, description: state.description, expiresInDays: state.expiration, }); requestState.setFinish(); onSuccess(response); if (response.token) { setCreatedToken(response.token); } else { onOpenChange(false); } } catch (error: unknown) { handleError(error, toast.error, { context: "Create access token", onError: () => requestState.setError(), }); } }; const handleCopyToken = () => { if (!createdToken) return; copy(createdToken); toast.success(t("message.copied")); }; useEffect(() => { if (!open) return; setState({ description: "", expiration: 30, }); setCreatedToken(null); }, [open]); return ( {t("setting.access-token.create-dialog.create-access-token")} {createdToken ? (