From c202764966a2d4df52bdc5d89aa3a25e6ae7d7db Mon Sep 17 00:00:00 2001 From: gom-by Date: Mon, 27 Jan 2025 10:15:05 +0100 Subject: [PATCH] events api file init --- backend/api/delete_event.go | 36 +++++++++++ backend/api/new_event.go | 17 ++--- backend/api/update_event.go | 91 +++++++++++++++++++++++++++ backend/main.go | 23 +++++-- frontend/app/(main)/planning/page.tsx | 61 +++++++++++------- frontend/hooks/events.tsx | 38 +++++++++++ 6 files changed, 226 insertions(+), 40 deletions(-) create mode 100644 backend/api/delete_event.go create mode 100644 backend/api/update_event.go create mode 100644 frontend/hooks/events.tsx diff --git a/backend/api/delete_event.go b/backend/api/delete_event.go new file mode 100644 index 0000000..ae3ded7 --- /dev/null +++ b/backend/api/delete_event.go @@ -0,0 +1,36 @@ + +package api + +import ( + "context" + "log" + "net/http" + + "fr.latosa-escrima/api/core" +) + +func HandleDeleteEvent(w http.ResponseWriter, r *http.Request) { + uuid := r.PathValue("event_uuid") + var event core.Event + res, err := core.DB.NewDelete(). + Model(&event). + Where("id = ?", uuid). + Returning("*"). + Exec(context.Background()) + if err != nil { + core.JSONError{ + Status: core.Error, + Message: err.Error(), + }.Respond(w, http.StatusInternalServerError) + return + } + log.Println(res) + + // TODO sql request to remove content + + core.JSONSuccess{ + Status: core.Success, + Message: "Event deleted.", + }.Respond(w, http.StatusOK) +} + diff --git a/backend/api/new_event.go b/backend/api/new_event.go index cefd342..dfd0abb 100644 --- a/backend/api/new_event.go +++ b/backend/api/new_event.go @@ -2,22 +2,16 @@ package api import ( "context" - "net/http" - "io" "encoding/json" + "io" + "log" + "net/http" + "time" core "fr.latosa-escrima/api/core" ) func HandleCreateEvent(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodPost { - core.JSONError{ - Status: core.Error, - Message: "Method is not allowed", - }.Respond(w, http.StatusMethodNotAllowed) - return - } - body, err := io.ReadAll(r.Body) if err != nil { core.JSONError{ @@ -26,6 +20,7 @@ func HandleCreateEvent(w http.ResponseWriter, r *http.Request) { }.Respond(w, http.StatusNoContent) return } + log.Println(time.Now()) var event core.Event if err = json.Unmarshal(body, &event); err != nil { core.JSONError{ @@ -41,7 +36,7 @@ func HandleCreateEvent(w http.ResponseWriter, r *http.Request) { Status: core.Error, Message: err.Error(), }.Respond(w, http.StatusNotAcceptable) - } + } core.JSONSuccess{ Status: core.Success, diff --git a/backend/api/update_event.go b/backend/api/update_event.go new file mode 100644 index 0000000..6a3e2d6 --- /dev/null +++ b/backend/api/update_event.go @@ -0,0 +1,91 @@ +package api + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + + "fr.latosa-escrima/api/core" +) + +type UpdateEventArgs struct { + FirstName *string `json:"firstname,omitempty"` + LastName *string `json:"lastname,omitempty"` + Email *string `json:"email,omitempty"` + Password *string `json:"password,omitempty"` + Phone *string `json:"phone,omitempty"` + Role *core.Role `json:"role,omitempty"` +} + +func HandleUpdateEvent(w http.ResponseWriter, r *http.Request) { + // var updateArgs UpdateEventArgs + body, err := io.ReadAll(r.Body) + if err != nil { + core.JSONError{ + Status: core.Error, + Message: err.Error(), + }.Respond(w, http.StatusInternalServerError) + return + } + fmt.Println("update and event here. Body : ", body) + var event core.Event + err = json.Unmarshal(body, &event) + if err != nil { + core.JSONError{ + Status: core.Error, + Message: err.Error(), + }.Respond(w, http.StatusInternalServerError) + return + } + + // var event core.Event + // updateQuery := core.DB.NewUpdate().Model(&event) + // + // val := reflect.ValueOf(updateArgs) + // typ := reflect.TypeOf(updateArgs) + // + // for i := 0; i < val.NumField(); i++ { + // field := val.Field(i) + // fieldname := typ.Field(i).Name + // + // tag := typ.Field(i).Tag.Get("bun") + // if tag == "" { + // tag = typ.Field(i).Tag.Get("json") + // } + // + // // Only add fields that are non-nil and non-zero + // if field.IsValid() && !field.IsNil() && !field.IsZero() { + // if fieldname == "Password" { + // updateQuery.Set(fmt.Sprintf("%s = crypt(?, gen_salt('bf'))", strings.Split(tag, ",")[0]), field.Interface()) + // } else { + // updateQuery.Set(fmt.Sprintf("%s = ?", strings.Split(tag, ",")[0]), field.Interface()) + // } + // } + // } + // + // // Always update the `updated_at` field + // updateQuery.Set("updated_at = ?", time.Now()) + // + // uuid := r.PathValue("user_uuid") + // _, err = updateQuery. + // Where("user_id = ?", uuid). + // Returning("*"). + // Exec(context.Background()) + // + // if err != nil { + // core.JSONError{ + // Status: core.Error, + // Message: err.Error(), + // }.Respond(w, http.StatusInternalServerError) + // return + // } + // + // user.Password = "" + // + core.JSONSuccess{ + Status: core.Success, + Message: "User updated.", + Data: "ok", + }.Respond(w, http.StatusOK) +} diff --git a/backend/main.go b/backend/main.go index e27b64e..ddea390 100644 --- a/backend/main.go +++ b/backend/main.go @@ -105,11 +105,24 @@ func main() { "/users/{user_uuid}/update": { Handler: api.HandleUpdateUser, Middlewares: []core.Middleware{api.Methods("PATCH"), api.AuthJWT}}, - // "/users/{user_uuid}/events": {Handler: nil, Middleware: nil}, - // "/users/{user_uuid}/events/{event_uuid}": {Handler: nil, Middleware: nil}, - // "/users/{user_uuid}/events/{event_uuid}/delete": {Handler: nil, Middleware: nil}, - // "/users/{user_uuid}/events/{event_uuid}/update": {Handler: nil, Middleware: nil}, - "/blogs/new": {Handler: api.HandleCreateBlog, Middlewares: nil}, + "/events": { + Handler: api.HandleGetEvent, + Middlewares: []core.Middleware{api.Methods("GET")}}, + "/events/new": { + Handler: api.HandleCreateEvent, + Middlewares: []core.Middleware{api.Methods("POST")}}, + "/events/{event_uuid}": { + Handler: api.HandleGetEvent, + Middlewares: []core.Middleware{api.Methods("GET")}}, + "/events/{event_uuid}/delete": { + Handler: api.HandleDeleteEvent, + Middlewares: []core.Middleware{api.Methods("DELETE")}}, + "/events/{event_uuid}/update": { + Handler: api.HandleUpdateEvent, + Middlewares: []core.Middleware{api.Methods("PATCH")}}, + "/blogs/new": { + Handler: api.HandleCreateBlog, + Middlewares: []core.Middleware{api.Methods(("POST"))}}, "/blogs/{uuid}": { Handler: api.HandleGetBlog, Middlewares: []core.Middleware{api.Methods("GET")}}, diff --git a/frontend/app/(main)/planning/page.tsx b/frontend/app/(main)/planning/page.tsx index 4079025..dbe47c7 100644 --- a/frontend/app/(main)/planning/page.tsx +++ b/frontend/app/(main)/planning/page.tsx @@ -1,5 +1,6 @@ "use client"; +import { request } from "@/hooks/use-api"; import "@schedule-x/theme-shadcn/dist/index.css"; import { useNextCalendarApp, ScheduleXCalendar } from "@schedule-x/react"; import { createEventsServicePlugin } from "@schedule-x/events-service"; @@ -36,7 +37,7 @@ const Planning = () => { useState(null); const [events, setEvents] = useState([ { - id: "1", + id: "1", // TODO put an uuid there title: "Event 1", start: format(new Date(Date.now()), "yyyy-MM-dd HH:mm"), end: format( @@ -45,6 +46,7 @@ const Planning = () => { ), }, ]); + const calendar = useNextCalendarApp( { theme: "shadcn", @@ -61,7 +63,7 @@ const Planning = () => { callbacks: { onEventClick(event, e) { setEventSelected(event); - }, + } }, }, plugins, @@ -78,7 +80,7 @@ const Planning = () => { { setEventSelected((e) => (open ? e : null)); }} @@ -137,10 +139,9 @@ const Planning = () => { */} { const val = e.currentTarget.value; - console.log(val); setEventSelected((ev) => { if (ev) return { @@ -159,36 +160,48 @@ const Planning = () => { + value={eventSelected?.end || ""} + onChange={(e) => { + const val = e.currentTarget.value setEventSelected((ev) => { if (ev) return { ...ev, - end: e.currentTarget.value, + end: val, }; return ev; }) - } + }} className="col-span-3" /> - - + diff --git a/frontend/hooks/events.tsx b/frontend/hooks/events.tsx new file mode 100644 index 0000000..a8b4eb5 --- /dev/null +++ b/frontend/hooks/events.tsx @@ -0,0 +1,38 @@ +"use client"; + +import { setCookie } from "cookies-next"; +import { useEffect, useState } from "react"; +import { API_URL } from "@/lib/constants"; + +export interface LoginArgs { + email: string; + password: string; +} + +export default function useLogin() { + const { + data, + isLoading: loading, + isSuccess, + } = request( + "/users/login", + undefined, + "POST", + false, + true, + ); + + const login = async (inputs: LoginArgs) => { + try { + const res = await trigger(inputs); + if (!res) throw new Error("The server hasn't responded."); + if (res.status === "Error") throw new Error(res.message); + if (res.data) setCookie("auth_token", res.data); + return res; + } catch (error: any) { + throw new Error(error.message); + } + }; + + return { login, loading, isSuccess }; +}