Compare commits

...

2 commits

Author SHA1 Message Date
Imbus
d0d1a1dfaa Gluing together the frontend and backend 2024-02-20 15:27:15 +01:00
Imbus
4554ddab6d Better button handler server-side 2024-02-20 15:26:28 +01:00
4 changed files with 64 additions and 15 deletions

View file

@ -12,15 +12,18 @@ import (
// The button state as represented in memory // The button state as represented in memory
type ButtonState struct { type ButtonState struct {
pressCount int PressCount int `json:"pressCount"`
} }
// This is what a handler with a receiver looks like // This is what a handler with a receiver looks like
// Keep in mind that concurrent state access is not (usually) safe // Keep in mind that concurrent state access is not (usually) safe
// And will in pracice be guarded by a mutex // And will in pracice be guarded by a mutex
func (b *ButtonState) pressHandler(w http.ResponseWriter, r *http.Request) { func (b *ButtonState) pressHandler(w http.ResponseWriter, r *http.Request) {
b.pressCount++ if r.Method != "POST" {
response, err := json.Marshal(b.pressCount) b.PressCount++
}
response, err := json.Marshal(b)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
@ -38,13 +41,13 @@ func handler(w http.ResponseWriter, r *http.Request) {
func main() { func main() {
database.DbConnect() database.DbConnect()
b := &ButtonState{pressCount: 0} b := &ButtonState{PressCount: 0}
// Mounting the handlers // Mounting the handlers
fs := http.FileServer(http.Dir("static")) fs := http.FileServer(http.Dir("static"))
http.Handle("/", fs) http.Handle("/", fs)
http.HandleFunc("/hello", handler) http.HandleFunc("/hello", handler)
http.HandleFunc("/button", b.pressHandler) http.HandleFunc("/api/button", b.pressHandler)
// Start the server on port 8080 // Start the server on port 8080
println("Currently listening on http://localhost:8080") println("Currently listening on http://localhost:8080")

View file

@ -1,11 +1,9 @@
import { useState } from "react";
import reactLogo from "./assets/react.svg"; import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg"; import viteLogo from "/vite.svg";
import "./App.css"; import "./App.css";
import { CountButton } from "./Components/CountButton";
function App(): JSX.Element { function App(): JSX.Element {
const [count, setCount] = useState(0);
return ( return (
<> <>
<div> <div>
@ -18,13 +16,7 @@ function App(): JSX.Element {
</div> </div>
<h1>Vite + React</h1> <h1>Vite + React</h1>
<div className="card"> <div className="card">
<button <CountButton />
onClick={() => {
setCount((count): number => count + 1);
}}
>
count is {count}
</button>
<p> <p>
Edit <code>src/App.tsx</code> and save to test HMR Edit <code>src/App.tsx</code> and save to test HMR
</p> </p>

View file

@ -0,0 +1,39 @@
import { useState, useEffect } from "react";
// Interface for the response from the server
// This should eventually reside in a dedicated file
interface CountResponse {
pressCount: number;
}
// Some constants for the button
const BUTTON_ENDPOINT = "/api/button";
// A simple button that counts how many times it's been pressed
export function CountButton(): JSX.Element {
const [count, setCount] = useState<number>(NaN);
// useEffect with a [] dependency array runs only once
useEffect(() => {
async function getCount(): Promise<void> {
const response = await fetch(BUTTON_ENDPOINT);
const data = (await response.json()) as CountResponse;
setCount(data.pressCount);
}
void getCount();
}, []);
// This is what runs on every button click
function press(): void {
async function pressPost(): Promise<void> {
await fetch(BUTTON_ENDPOINT, { method: "POST" });
const response = await fetch(BUTTON_ENDPOINT);
const data = (await response.json()) as CountResponse;
setCount(data.pressCount);
}
void pressPost();
}
// Return some JSX with the button and associated handler
return <button onClick={press}>count is {count}</button>;
}

View file

@ -4,4 +4,19 @@ import react from "@vitejs/plugin-react-swc";
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react()], plugins: [react()],
// build: {
// outDir: '../server/public' // Override default outDir('dist')
// },
server: {
port: 3000,
open: true,
proxy: {
"/api": {
target: "http://localhost:8080/api",
changeOrigin: true,
secure: false,
rewrite: (path): string => path.replace(/^\/api/, ""),
},
},
},
}); });