blob: 931e7b5d2a85461f2cdb4cd6963f6c692330e081 [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 (
73 <div className="px-5 space-y-6">
74 <div>
75 <h3 className="text-md font-medium mb-2">GitHub</h3>
76 <div className="space-y-4">
77 <div className="flex items-center space-x-2">
78 <Checkbox checked={!!githubService} disabled />
79 <label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
80 GitHub Access Token
81 </label>
82 </div>
gio7f98e772025-05-07 11:00:14 +000083
giod0026612025-05-08 13:00:36 +000084 {!!githubService && !isEditing && (
85 <Button variant="outline" onClick={() => setIsEditing(true)}>
86 Update Access Token
87 </Button>
88 )}
gio7f98e772025-05-07 11:00:14 +000089
giod0026612025-05-08 13:00:36 +000090 {(!githubService || isEditing) && (
91 <Form {...form}>
92 <form className="space-y-4" onSubmit={form.handleSubmit(onSubmit)}>
93 <FormField
94 control={form.control}
95 name="githubToken"
96 render={({ field }) => (
97 <FormItem>
98 <FormControl>
99 <Input
100 type="password"
101 placeholder="GitHub Personal Access Token"
102 className="border border-black"
103 {...field}
104 />
105 </FormControl>
106 <FormMessage />
107 </FormItem>
108 )}
109 />
110 <div className="flex space-x-2">
111 <Button type="submit" disabled={isSaving}>
112 {isSaving ? "Saving..." : "Save"}
113 </Button>
114 {!!githubService && (
115 <Button
116 type="button"
117 variant="outline"
118 onClick={handleCancel}
119 disabled={isSaving}
120 >
121 Cancel
122 </Button>
123 )}
124 </div>
125 </form>
126 </Form>
127 )}
128 </div>
129 </div>
130 </div>
131 );
132}