blob: 436c1e80a252d8b99f30506fb213fd8716581fff [file] [log] [blame]
giod0026612025-05-08 13:00:36 +00001import { useProjectId, useGithubService, useStateStore } from "@/lib/state";
2import { Form, FormControl, FormField, FormItem, FormMessage } from "./components/ui/form";
3import { Input } from "./components/ui/input";
4import { useForm } from "react-hook-form";
5import { z } from "zod";
6import { zodResolver } from "@hookform/resolvers/zod";
7import { Button } from "./components/ui/button";
8import { useToast } from "@/hooks/use-toast";
9import { Checkbox } from "./components/ui/checkbox";
10import { useState, useCallback } from "react";
gio7f98e772025-05-07 11:00:14 +000011
12const schema = z.object({
giod0026612025-05-08 13:00:36 +000013 githubToken: z.string().min(1, "GitHub token is required"),
gio7f98e772025-05-07 11:00:14 +000014});
15
16export function Integrations() {
giod0026612025-05-08 13:00:36 +000017 const { toast } = useToast();
18 const store = useStateStore();
19 const projectId = useProjectId();
20 const [isEditing, setIsEditing] = useState(false);
21 const githubService = useGithubService();
22 const [isSaving, setIsSaving] = useState(false);
gio7f98e772025-05-07 11:00:14 +000023
giod0026612025-05-08 13:00:36 +000024 const form = useForm<z.infer<typeof schema>>({
25 resolver: zodResolver(schema),
26 mode: "onChange",
27 });
gio7f98e772025-05-07 11:00:14 +000028
giod0026612025-05-08 13:00:36 +000029 const onSubmit = useCallback(
30 async (data: z.infer<typeof schema>) => {
31 if (!projectId) return;
gio7f98e772025-05-07 11:00:14 +000032
giod0026612025-05-08 13:00:36 +000033 setIsSaving(true);
gio7f98e772025-05-07 11:00:14 +000034
giod0026612025-05-08 13:00:36 +000035 try {
36 const response = await fetch(`/api/project/${projectId}/github-token`, {
37 method: "POST",
38 headers: {
39 "Content-Type": "application/json",
40 },
41 body: JSON.stringify({ githubToken: data.githubToken }),
42 });
gio7f98e772025-05-07 11:00:14 +000043
giod0026612025-05-08 13:00:36 +000044 if (!response.ok) {
45 throw new Error("Failed to save GitHub token");
46 }
gio7f98e772025-05-07 11:00:14 +000047
giod0026612025-05-08 13:00:36 +000048 await store.refreshEnv();
49 setIsEditing(false);
50 form.reset();
51 toast({
52 title: "GitHub token saved successfully",
53 });
54 } catch (error) {
55 toast({
56 variant: "destructive",
57 title: "Failed to save GitHub token",
58 description: error instanceof Error ? error.message : "Unknown error",
59 });
60 } finally {
61 setIsSaving(false);
62 }
63 },
64 [projectId, store, form, toast, setIsEditing, setIsSaving],
65 );
gio7f98e772025-05-07 11:00:14 +000066
giod0026612025-05-08 13:00:36 +000067 const handleCancel = () => {
68 setIsEditing(false);
69 form.reset();
70 };
gio7f98e772025-05-07 11:00:14 +000071
giod0026612025-05-08 13:00:36 +000072 return (
giobc47f9f2025-05-12 08:31:07 +000073 <div className="px-4 py-1 space-y-6">
giod0026612025-05-08 13:00:36 +000074 <div>
gio3a921b82025-05-10 07:36:09 +000075 <div className="flex items-center space-x-2">
76 <Checkbox checked={!!githubService} disabled />
77 <label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
78 <h3 className="text-md font-medium mb-2">GitHub</h3>
79 </label>
giod0026612025-05-08 13:00:36 +000080 </div>
gio3a921b82025-05-10 07:36:09 +000081
82 {!!githubService && !isEditing && (
83 <Button variant="outline" onClick={() => setIsEditing(true)}>
84 Update Access Token
85 </Button>
86 )}
87
88 {(!githubService || isEditing) && (
89 <Form {...form}>
90 <form className="space-y-4" onSubmit={form.handleSubmit(onSubmit)}>
91 <FormField
92 control={form.control}
93 name="githubToken"
94 render={({ field }) => (
95 <FormItem>
96 <FormControl>
97 <Input
98 type="password"
99 placeholder="GitHub Personal Access Token"
100 className="border border-black"
101 {...field}
102 />
103 </FormControl>
104 <FormMessage />
105 </FormItem>
106 )}
107 />
108 <div className="flex space-x-2">
109 <Button type="submit" disabled={isSaving}>
110 {isSaving ? "Saving..." : "Save"}
111 </Button>
112 {!!githubService && (
113 <Button type="button" variant="outline" onClick={handleCancel} disabled={isSaving}>
114 Cancel
115 </Button>
116 )}
117 </div>
118 </form>
119 </Form>
120 )}
giod0026612025-05-08 13:00:36 +0000121 </div>
122 </div>
123 );
124}