Compare commits
2 commits
ebe2a42f91
...
d0d1a1dfaa
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d0d1a1dfaa | ||
![]() |
4554ddab6d |
4 changed files with 64 additions and 15 deletions
|
@ -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")
|
||||||
|
|
|
@ -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>
|
||||||
|
|
39
frontend/src/Components/CountButton.tsx
Normal file
39
frontend/src/Components/CountButton.tsx
Normal 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>;
|
||||||
|
}
|
|
@ -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/, ""),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue