diff --git a/backend/main.go b/backend/main.go index 16acd2b..7403748 100644 --- a/backend/main.go +++ b/backend/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "fmt" + "io/fs" "net/http" "os" "os/signal" @@ -11,6 +11,7 @@ import ( "codeberg.org/u1f320/pronouns.cc/backend/log" "codeberg.org/u1f320/pronouns.cc/backend/server" "codeberg.org/u1f320/pronouns.cc/frontend" + "emperror.dev/errors" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" @@ -56,40 +57,39 @@ func main() { func setupFrontend(r chi.Router, s *server.Server) { r.Use(middleware.Recoverer) - r.Get("/@{user}", a) - r.Get("/@{user}/{member}", a) + r.Get("/@{user}", nil) + r.Get("/@{user}/{member}", nil) r.Mount("/api", s.Router) r.NotFound(func(w http.ResponseWriter, r *http.Request) { - var ( - data []byte - err error - ) + data, err := frontend.Data.ReadFile("dist" + r.URL.Path) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + data, err = frontend.Data.ReadFile("dist/index.html") + if err != nil && !errors.Is(err, fs.ErrNotExist) { + log.Errorf("serving frontend file: %v", err) + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } + + http.Error(w, "Not found", http.StatusNotFound) + return + } + + log.Errorf("serving frontend file: %v", err) + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } if strings.HasSuffix(r.URL.Path, ".js") { - data, err = frontend.Data.ReadFile("dist" + r.URL.Path) w.Header().Add("content-type", "application/javascript") } else if strings.HasSuffix(r.URL.Path, ".css") { - data, err = frontend.Data.ReadFile("dist" + r.URL.Path) w.Header().Add("content-type", "text/css") - } else if strings.HasSuffix(r.URL.Path, ".map") { - data, err = frontend.Data.ReadFile("dist" + r.URL.Path) } else { - data, err = frontend.Data.ReadFile("dist/index.html") w.Header().Add("content-type", "text/html") } - if err != nil { - panic(err) - } w.Write(data) }) } - -func a(w http.ResponseWriter, r *http.Request) { - user := chi.URLParam(r, "user") - member := chi.URLParam(r, "member") - - fmt.Fprintf(w, "user: %v, member: %v", user, member) -} diff --git a/frontend/src/lib/Card.tsx b/frontend/src/lib/Card.tsx index 769357a..92189ff 100644 --- a/frontend/src/lib/Card.tsx +++ b/frontend/src/lib/Card.tsx @@ -1,4 +1,4 @@ -import React, { ReactNode, PropsWithChildren } from "react"; +import React, { ReactNode } from "react"; export type Props = { children?: ReactNode | undefined; diff --git a/frontend/src/lib/fetch.ts b/frontend/src/lib/fetch.ts index c2cbfc0..31f3a0b 100644 --- a/frontend/src/lib/fetch.ts +++ b/frontend/src/lib/fetch.ts @@ -4,7 +4,7 @@ import type { APIError } from "./types"; export default async function fetchAPI( path: string, method = "GET", - body = null + body: any = null ) { let headers = {}; const token = localStorage.getItem("pronouns-token"); diff --git a/frontend/src/pages/EditMe.tsx b/frontend/src/pages/EditMe.tsx index 75be106..c7e6759 100644 --- a/frontend/src/pages/EditMe.tsx +++ b/frontend/src/pages/EditMe.tsx @@ -12,13 +12,13 @@ import { People, Trash3, } from "react-bootstrap-icons"; -import CreatableSelect from "react-select/creatable"; import { userState } from "../lib/store"; -import { Field } from "../lib/types"; import Loading from "../lib/Loading"; import Card from "../lib/Card"; import TextInput from "../lib/TextInput"; +import fetchAPI from "../lib/fetch"; +import { MeUser, Field } from "../lib/types"; interface EditField { id: number; @@ -46,6 +46,51 @@ function fieldsEqual(arr1: EditField[], arr2: EditField[]) { ); } +async function updateUser(args: { + displayName: string; + bio: string; + fields: EditField[]; +}) { + const newFields = args.fields.map((editField) => { + const field: Field = { + name: editField.name, + favourite: [], + okay: [], + jokingly: [], + friends_only: [], + avoid: [], + }; + + Object.keys(editField).forEach((pronoun) => { + switch (editField.pronouns[pronoun]) { + case PronounChoice.favourite: + field.favourite?.push(pronoun); + break; + case PronounChoice.okay: + field.okay?.push(pronoun); + break; + case PronounChoice.jokingly: + field.jokingly?.push(pronoun); + break; + case PronounChoice.friendsOnly: + field.friends_only?.push(pronoun); + break; + case PronounChoice.avoid: + field.avoid?.push(pronoun); + break; + } + }); + + return field; + }); + + return await fetchAPI("/users/@me", "PATCH", { + display_name: args.displayName, + bio: args.bio, + fields: newFields, + }); +} + export default function EditMe() { const navigate = useNavigate(); @@ -69,19 +114,19 @@ export default function EditMe() { pronouns: {}, }; - f.favourite.forEach((val) => { + f.favourite?.forEach((val) => { field.pronouns[val] = PronounChoice.favourite; }); - f.okay.forEach((val) => { + f.okay?.forEach((val) => { field.pronouns[val] = PronounChoice.okay; }); - f.jokingly.forEach((val) => { + f.jokingly?.forEach((val) => { field.pronouns[val] = PronounChoice.jokingly; }); - f.friends_only.forEach((val) => { + f.friends_only?.forEach((val) => { field.pronouns[val] = PronounChoice.friendsOnly; }); - f.avoid.forEach((val) => { + f.avoid?.forEach((val) => { field.pronouns[val] = PronounChoice.avoid; });