@@ -4,6 +4,7 @@ import { useState } from "react";
44
55interface SummaryFormProps {
66 groups : string [ ] ;
7+ authTokenNames : string [ ] ;
78}
89
910function getISOWeek ( date : Date ) : number {
@@ -28,7 +29,7 @@ const WEEK_OPTIONS = Array.from({ length: 52 }, (_, i) => {
2829const DEFAULT_PROMPT =
2930 "Summarize the following messages. Give a concise overview of the key topics, decisions, and action items discussed:" ;
3031
31- export default function SummaryForm ( { groups } : SummaryFormProps ) {
32+ export default function SummaryForm ( { groups, authTokenNames } : SummaryFormProps ) {
3233 const [ group , setGroup ] = useState ( groups [ 0 ] ?? "" ) ;
3334 const [ week , setWeek ] = useState ( `week${ String ( currentWeek ) . padStart ( 2 , "0" ) } ` ) ;
3435 const [ prompt , setPrompt ] = useState ( DEFAULT_PROMPT ) ;
@@ -38,6 +39,13 @@ export default function SummaryForm({ groups }: SummaryFormProps) {
3839 const [ weekLabel , setWeekLabel ] = useState ( "" ) ;
3940 const [ error , setError ] = useState ( "" ) ;
4041
42+ // Publish state
43+ const [ publishGroup , setPublishGroup ] = useState ( groups [ 0 ] ?? "" ) ;
44+ const [ publishAs , setPublishAs ] = useState ( authTokenNames [ 0 ] ?? "" ) ;
45+ const [ publishing , setPublishing ] = useState ( false ) ;
46+ const [ publishStatus , setPublishStatus ] = useState < "idle" | "success" | "error" > ( "idle" ) ;
47+ const [ publishError , setPublishError ] = useState ( "" ) ;
48+
4149 async function handleSubmit ( e : React . FormEvent ) {
4250 e . preventDefault ( ) ;
4351 setLoading ( true ) ;
@@ -75,6 +83,44 @@ export default function SummaryForm({ groups }: SummaryFormProps) {
7583 }
7684 }
7785
86+ async function handlePublish ( ) {
87+ setPublishing ( true ) ;
88+ setPublishStatus ( "idle" ) ;
89+ setPublishError ( "" ) ;
90+
91+ try {
92+ const res = await fetch ( "/api/summary/publish" , {
93+ method : "POST" ,
94+ headers : { "Content-Type" : "application/json" } ,
95+ body : JSON . stringify ( {
96+ targetGroup : publishGroup ,
97+ authTokenName : publishAs ,
98+ markdown : summary ,
99+ } ) ,
100+ } ) ;
101+
102+ const text = await res . text ( ) ;
103+ let data : Record < string , unknown > ;
104+ try {
105+ data = JSON . parse ( text ) ;
106+ } catch {
107+ throw new Error ( `Server error (HTTP ${ res . status } )` ) ;
108+ }
109+
110+ if ( ! res . ok ) {
111+ throw new Error ( ( data . error as string ) || `HTTP ${ res . status } ` ) ;
112+ }
113+
114+ setPublishStatus ( "success" ) ;
115+ setTimeout ( ( ) => setPublishStatus ( "idle" ) , 5000 ) ;
116+ } catch ( err ) {
117+ setPublishStatus ( "error" ) ;
118+ setPublishError ( err instanceof Error ? err . message : String ( err ) ) ;
119+ } finally {
120+ setPublishing ( false ) ;
121+ }
122+ }
123+
78124 return (
79125 < div className = "sum-section" >
80126 < form className = "sum-form" onSubmit = { handleSubmit } >
@@ -159,6 +205,56 @@ export default function SummaryForm({ groups }: SummaryFormProps) {
159205 </ span >
160206 </ div >
161207 < div className = "sum-result-body" > { summary } </ div >
208+
209+ < div className = "sum-publish" >
210+ < div className = "sum-publish-header" > Publish</ div >
211+ < div className = "sum-form-row" >
212+ < div className = "sum-field" >
213+ < label htmlFor = "sum-publish-group" > Post to</ label >
214+ < select
215+ id = "sum-publish-group"
216+ value = { publishGroup }
217+ onChange = { ( e ) => setPublishGroup ( e . target . value ) }
218+ >
219+ { groups . map ( ( g ) => (
220+ < option key = { g } value = { g } > { g } </ option >
221+ ) ) }
222+ </ select >
223+ </ div >
224+ < div className = "sum-field" >
225+ < label htmlFor = "sum-publish-as" > Post as</ label >
226+ < select
227+ id = "sum-publish-as"
228+ value = { publishAs }
229+ onChange = { ( e ) => setPublishAs ( e . target . value ) }
230+ >
231+ { authTokenNames . map ( ( t ) => (
232+ < option key = { t } value = { t } > { t } </ option >
233+ ) ) }
234+ </ select >
235+ </ div >
236+ < div className = "sum-field sum-field--action" >
237+ < button
238+ type = "button"
239+ className = "sum-publish-btn"
240+ disabled = { publishing }
241+ onClick = { handlePublish }
242+ >
243+ { publishing ? "Publishing..." : "Publish" }
244+ </ button >
245+ </ div >
246+ </ div >
247+ { publishStatus === "success" && (
248+ < div className = "sum-publish-status sum-publish-status--ok" >
249+ Published to { publishGroup }
250+ </ div >
251+ ) }
252+ { publishStatus === "error" && (
253+ < div className = "sum-publish-status sum-publish-status--err" >
254+ { publishError }
255+ </ div >
256+ ) }
257+ </ div >
162258 </ div >
163259 ) }
164260 </ div >
0 commit comments