11import { serialize } from "cookie"
22import { GetServerSideProps } from "next"
33import Head from "next/head"
4- import { Component } from "react"
4+ import { useRouter } from "next/router"
5+ import { Component , useState } from "react"
6+ import ReactModal from "react-modal"
57import Main from "../../components/Main"
68import { config } from "../../utils/config"
79import { parseUser } from "../../utils/parse-user"
810import { DiscordUser , Reminder } from "../../utils/types"
11+ import { send } from "../../utils/utils"
912
1013interface Props {
1114 user : DiscordUser
1215 reminders : Reminder [ ]
1316}
1417
15- export default class Reminders extends Component < Props , { reminders : Reminder [ ] } > {
18+ const modalStyle : ReactModal . Styles = {
19+ overlay : {
20+ backgroundColor : "rgba(0, 0, 0, 0.66)"
21+ } ,
22+ content : {
23+ position : "absolute" ,
24+ top : "min(10%, 200px)" ,
25+ bottom : "auto" ,
26+
27+ width : "min(42rem, calc(100% - 40px))" ,
28+ left : "max(calc(50% - (42rem/2)), 20px)" ,
29+
30+ border : "1px solid rgb(64, 79, 100)" ,
31+ color : "white" ,
32+ background : "rgb(51 65 85)" ,
33+ borderRadius : "1rem"
34+ }
35+ }
36+ const erorrModalStyle : ReactModal . Styles = {
37+ overlay : {
38+ backgroundColor : "rgba(10, 0, 0, 0.66)"
39+ } ,
40+ content : {
41+ position : "absolute" ,
42+ top : "max(calc(50% - (10rem/2)), 20px)" ,
43+ maxHeight : "10rem" ,
44+
45+ width : "min(20rem, calc(100% - 40px))" ,
46+ left : "max(calc(50% - (20rem/2)), 20px)" ,
47+
48+ border : "1px solid rgb(156, 79, 100)" ,
49+ color : "white" ,
50+ background : "rgb(156 65 85)" ,
51+ borderRadius : "1rem"
52+ }
53+ }
54+
55+ export default class Reminders extends Component < Props , { reminders : Reminder [ ] , createReminderOpen : boolean } > {
1656 constructor ( props : Props ) {
1757 super ( props )
1858 this . state = {
19- reminders : this . props . reminders
59+ reminders : this . props . reminders ,
60+ createReminderOpen : false
2061 }
2162 }
2263
@@ -37,21 +78,99 @@ export default class Reminders extends Component<Props, { reminders: Reminder[]
3778 </ h1 >
3879 < div className = "text-base" > Logged in as: < DiscordAvatar user = { user } /> { user . username } < span className = "text-xs" > #{ user . discriminator } </ span > </ div >
3980 < div className = "text-xl mt-3" > { reminders . length } reminder{ reminders . length == 1 ? "" : "s" } </ div >
40- { reminders . map ( r => < ReminderCard r = { r } key = { r . id } onDelete = { ( ) => this . setState ( {
41- reminders : reminders . filter ( re => r . id != re . id )
42- } ) } /> ) }
81+ { reminders . map ( r => < ReminderCard
82+ r = { r }
83+ key = { r . id }
84+ onDelete = { ( ) => this . setState ( {
85+ reminders : reminders . filter ( re => r . id != re . id )
86+ } ) }
87+ /> ) }
88+ < div className = "flex flex-wrap gap-2" >
89+ < span className = "bg-blue-600 text-slate-50 w-fit px-3 py-1 text-center rounded-lg mt-2 cursor-pointer" onClick = { ( ) => fetch ( "/api/sendmessage" , {
90+ headers : { "Content-Type" : "application/json" } ,
91+ method : "POST"
92+ } ) } > Send test message</ span >
93+ < span className = "bg-green-600 text-slate-50 w-fit px-3 py-1 text-center rounded-lg mt-2 cursor-pointer" onClick = { ( ) => this . setState ( { createReminderOpen : true } ) } > Create reminder</ span >
94+ < CreateReminder
95+ isOpen = { this . state . createReminderOpen }
96+ requestClose = { ( ) => this . setState ( { createReminderOpen : false } ) }
97+ addReminder = { ( r ) => this . setState ( { reminders : [ ...reminders , r ] } ) }
98+ />
99+ </ div >
43100 </ Main >
44101 )
45102 }
46103}
47104
105+ function CreateReminder ( { isOpen, requestClose, addReminder } : { isOpen : boolean , requestClose : ( ) => void , addReminder : ( r : Reminder ) => void } ) {
106+ const [ name , setName ] = useState ( "" )
107+ const [ duration , setDuration ] = useState ( "" )
108+
109+ const [ error , setError ] = useState ( "" )
110+
111+ async function createReminder ( name : string , duration : string ) {
112+ if ( name . length > 128 ) return setError ( "Name too long" )
113+ if ( name . length == 0 ) return setError ( "No name given" )
114+ if ( duration . length == 0 ) return setError ( "No duration given" )
115+
116+ const res = await send ( "/api/reminders/create" , { name, duration } )
117+
118+ if ( ( res . status >= 200 && res . status < 300 ) ) {
119+ requestClose ( )
120+ addReminder ( await res . json ( ) )
121+
122+ setName ( "" )
123+ setDuration ( "" )
124+ } else {
125+ return setError ( "An error occurred... Try again later" )
126+ }
127+ }
128+ return < ReactModal style = { modalStyle } isOpen = { isOpen } onRequestClose = { requestClose } ariaHideApp = { false } >
129+ < ReactModal style = { erorrModalStyle } isOpen = { error . length > 0 } onRequestClose = { ( ) => setError ( "" ) } ariaHideApp = { false } >
130+ < div className = "flex flex-1 justify-center items-center h-full" onKeyDown = { ( ) => setError ( "" ) } >
131+ < div className = "font-semibold text-xl" >
132+ { error }
133+ </ div >
134+ </ div >
135+ </ ReactModal >
136+
137+ < h4 className = "text-lg font-semibold" > Create a reminder</ h4 >
138+ < div className = "flex flex-col" >
139+ < form onSubmit = { ( e ) => {
140+ e . preventDefault ( )
141+ createReminder ( name , duration )
142+ } } >
143+ < TextInput value = { name } set = { setName } placeholder = "Enter a name" maxLength = { 128 } label = "Name:" />
144+ < TextInput value = { duration } set = { setDuration } placeholder = "Enter a duration (ex. 10 hours 2 resin 5s)" maxLength = { 128 } label = "Duration:" />
145+ < button className = "bg-green-600 text-slate-50 w-fit px-3 py-1 text-center rounded-lg mt-2 cursor-pointer" formAction = "submit" > Create reminder</ button >
146+ </ form >
147+ </ div >
148+ < br />
149+
150+ < h4 className = "text-lg font-semibold" > Presets</ h4 >
151+ < div className = "flex flex-wrap gap-2" >
152+ < span className = "bg-green-600 text-slate-50 w-fit px-3 py-1 text-center rounded-lg mt-2 cursor-pointer" onClick = { ( ) => createReminder ( "Parametric" , "6d22h" ) } > Parametric (6d22h)</ span >
153+ < span className = "bg-green-600 text-slate-50 w-fit px-3 py-1 text-center rounded-lg mt-2 cursor-pointer" onClick = { ( ) => createReminder ( "Ores" , "72h" ) } > Ores (72h)</ span >
154+ </ div >
155+ </ ReactModal >
156+ }
157+
158+ function TextInput ( { value, set, maxLength, placeholder, label } : { value : string , set : ( newValue : string ) => unknown , maxLength ?: number , placeholder : string , label : string } ) {
159+ return < div > < label >
160+ { label }
161+ < input
162+ className = "bg-slate-800 rounded-lg px-2 ml-2 mt-1"
163+ value = { value }
164+ onChange = { ( e ) => set ( e . target . value ) }
165+ placeholder = { placeholder }
166+ maxLength = { maxLength }
167+ />
168+ </ label > </ div >
169+ }
170+
48171function ReminderCard ( { r, onDelete } : { r : Reminder , onDelete : ( ) => void } ) {
49172 const deleteReminder = async ( ) => {
50- const res = await fetch ( "/api/reminders/delete" , {
51- body : JSON . stringify ( { r } ) ,
52- headers : { "Content-Type" : "application/json" } ,
53- method : "POST"
54- } )
173+ const res = await send ( "/api/reminders/delete" , { r } )
55174
56175 if ( ( res . status >= 200 && res . status < 300 ) || res . status == 404 )
57176 onDelete ( )
@@ -86,7 +205,8 @@ export const getServerSideProps: GetServerSideProps<Props> = async function (ctx
86205 maxAge : 3600 ,
87206 sameSite : "lax" ,
88207 path : "/" ,
89- } ) )
208+ } )
209+ )
90210
91211 return {
92212 redirect : {
0 commit comments