blob: 436c1e80a252d8b99f30506fb213fd8716581fff [file] [log] [blame]
import { useProjectId, useGithubService, useStateStore } from "@/lib/state";
import { Form, FormControl, FormField, FormItem, FormMessage } from "./components/ui/form";
import { Input } from "./components/ui/input";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { Button } from "./components/ui/button";
import { useToast } from "@/hooks/use-toast";
import { Checkbox } from "./components/ui/checkbox";
import { useState, useCallback } from "react";
const schema = z.object({
githubToken: z.string().min(1, "GitHub token is required"),
});
export function Integrations() {
const { toast } = useToast();
const store = useStateStore();
const projectId = useProjectId();
const [isEditing, setIsEditing] = useState(false);
const githubService = useGithubService();
const [isSaving, setIsSaving] = useState(false);
const form = useForm<z.infer<typeof schema>>({
resolver: zodResolver(schema),
mode: "onChange",
});
const onSubmit = useCallback(
async (data: z.infer<typeof schema>) => {
if (!projectId) return;
setIsSaving(true);
try {
const response = await fetch(`/api/project/${projectId}/github-token`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ githubToken: data.githubToken }),
});
if (!response.ok) {
throw new Error("Failed to save GitHub token");
}
await store.refreshEnv();
setIsEditing(false);
form.reset();
toast({
title: "GitHub token saved successfully",
});
} catch (error) {
toast({
variant: "destructive",
title: "Failed to save GitHub token",
description: error instanceof Error ? error.message : "Unknown error",
});
} finally {
setIsSaving(false);
}
},
[projectId, store, form, toast, setIsEditing, setIsSaving],
);
const handleCancel = () => {
setIsEditing(false);
form.reset();
};
return (
<div className="px-4 py-1 space-y-6">
<div>
<div className="flex items-center space-x-2">
<Checkbox checked={!!githubService} disabled />
<label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
<h3 className="text-md font-medium mb-2">GitHub</h3>
</label>
</div>
{!!githubService && !isEditing && (
<Button variant="outline" onClick={() => setIsEditing(true)}>
Update Access Token
</Button>
)}
{(!githubService || isEditing) && (
<Form {...form}>
<form className="space-y-4" onSubmit={form.handleSubmit(onSubmit)}>
<FormField
control={form.control}
name="githubToken"
render={({ field }) => (
<FormItem>
<FormControl>
<Input
type="password"
placeholder="GitHub Personal Access Token"
className="border border-black"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="flex space-x-2">
<Button type="submit" disabled={isSaving}>
{isSaving ? "Saving..." : "Save"}
</Button>
{!!githubService && (
<Button type="button" variant="outline" onClick={handleCancel} disabled={isSaving}>
Cancel
</Button>
)}
</div>
</form>
</Form>
)}
</div>
</div>
);
}