You've already forked microservices
mirror of
https://github.com/ebosas/microservices.git
synced 2025-08-24 20:08:55 +02:00
Finish messages page
This commit is contained in:
@@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/go-redis/redis/v8"
|
"github.com/go-redis/redis/v8"
|
||||||
)
|
)
|
||||||
|
|
||||||
// handleAPICache handles an API call for cached messages
|
// handleAPICache handles API calls for cached messages
|
||||||
func handleAPICache(cr *redis.Client) func(w http.ResponseWriter, r *http.Request) {
|
func handleAPICache(cr *redis.Client) func(w http.ResponseWriter, r *http.Request) {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
data, err := cache.GetCacheJSON(cr)
|
data, err := cache.GetCacheJSON(cr)
|
||||||
|
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"embed"
|
"embed"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
"log"
|
||||||
@@ -72,12 +73,31 @@ func handleHome(w http.ResponseWriter, r *http.Request) {
|
|||||||
// handleMessages handles the messages page.
|
// handleMessages handles the messages page.
|
||||||
func handleMessages(cr *redis.Client) func(w http.ResponseWriter, r *http.Request) {
|
func handleMessages(cr *redis.Client) func(w http.ResponseWriter, r *http.Request) {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
data, err := cache.GetCache(cr)
|
cacheJSON, err := cache.GetCacheJSON(cr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("get cache: %s", err)
|
log.Printf("get cache: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cached cache.Cache
|
||||||
|
err = json.Unmarshal([]byte(cacheJSON), &cached)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("unmarshal cache: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"Data": cached,
|
||||||
|
"Json": cacheJSON,
|
||||||
|
}
|
||||||
|
|
||||||
|
// data := struct {
|
||||||
|
// Data cache.Cache
|
||||||
|
// Json string
|
||||||
|
// }{cached, "Hello"}
|
||||||
|
|
||||||
|
// fmt.Println(data.Json)
|
||||||
|
|
||||||
funcMap := template.FuncMap{"fdate": formatTime}
|
funcMap := template.FuncMap{"fdate": formatTime}
|
||||||
t := template.Must(template.New("").Funcs(funcMap).ParseFS(filesTempl, "template/template.html", "template/navbar.html", "template/messages.html"))
|
t := template.Must(template.New("").Funcs(funcMap).ParseFS(filesTempl, "template/template.html", "template/navbar.html", "template/messages.html"))
|
||||||
t.ExecuteTemplate(w, "layout", data)
|
t.ExecuteTemplate(w, "layout", data)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{{ define "content" }}
|
{{ define "content" }}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h3 class="my-4 ps-2">Recent messages ({{ .Count }}/{{ .Total }})</h3>
|
<h3 class="my-4 ps-2">Recent messages ({{ .Data.Count }}/{{ .Data.Total }})</h3>
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{{ range .Messages }}
|
{{ range .Data.Messages }}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ .Time | fdate }}</td>
|
<td>{{ .Time | fdate }}</td>
|
||||||
<td>{{ .Text }}</td>
|
<td>{{ .Text }}</td>
|
||||||
|
@@ -5,13 +5,15 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="static/build/style.css">
|
<link rel="stylesheet" href="static/build/style.css">
|
||||||
|
{{ if and . .Json }}<script>window.__DATA="{{ .Json }}"</script>{{ end }}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root" class="vh-100">
|
<div id="root" class="vh-100">
|
||||||
{{ template "navbar" . }}
|
{{ template "navbar" . }}
|
||||||
{{ template "content" . }}
|
{{ template "content" . }}
|
||||||
</div>
|
</div>
|
||||||
<script src="http://127.0.0.1:8000/index.js"></script>
|
|
||||||
<!-- <script src="static/build/index.js"></script> -->
|
<script src="http://127.0.0.1:8000/index.js"></script>
|
||||||
|
<!-- <script src="static/build/index.js"></script> -->
|
||||||
</body>
|
</body>
|
||||||
</html>{{ end }}
|
</html>{{ end }}
|
5
web/react/package-lock.json
generated
5
web/react/package-lock.json
generated
@@ -12,6 +12,11 @@
|
|||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"date-fns": {
|
||||||
|
"version": "2.25.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz",
|
||||||
|
"integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w=="
|
||||||
|
},
|
||||||
"esbuild": {
|
"esbuild": {
|
||||||
"version": "0.12.5",
|
"version": "0.12.5",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.5.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.5.tgz",
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"date-fns": "^2.25.0",
|
||||||
"esbuild": "^0.12.5",
|
"esbuild": "^0.12.5",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
|
@@ -2,6 +2,7 @@ import * as React from 'react'
|
|||||||
import * as ReactDOM from 'react-dom'
|
import * as ReactDOM from 'react-dom'
|
||||||
import App from './app';
|
import App from './app';
|
||||||
|
|
||||||
|
// ReactDOM.hydrate(
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<App />,
|
<App />,
|
||||||
document.getElementById('root')
|
document.getElementById('root')
|
||||||
|
@@ -1,57 +1,71 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { format } from 'date-fns'
|
||||||
|
|
||||||
|
let data = window.__DATA || null;
|
||||||
|
data = data ? JSON.parse(data) : null;
|
||||||
|
window.__DATA = null;
|
||||||
|
|
||||||
function Messages() {
|
function Messages() {
|
||||||
const [error, setError] = React.useState(null);
|
const [error, setError] = React.useState(data ? false : null);
|
||||||
const [isLoaded, setIsLoaded] = React.useState(false);
|
const [isLoaded, setIsLoaded] = React.useState(data ? true : false);
|
||||||
const [items, setItems] = React.useState([]);
|
const [messages, setMessages] = React.useState(data ? data.messages : []);
|
||||||
|
const [counts, setCounts] = React.useState(data ? {count: data.count, total: data.total} : {});
|
||||||
|
|
||||||
|
data = null;
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
fetch("/api/cache")
|
if (isLoaded) return;
|
||||||
.then(res => res.json())
|
|
||||||
.then(
|
|
||||||
(result) => {
|
|
||||||
setIsLoaded(true);
|
|
||||||
setItems(result);
|
|
||||||
console.log(result);
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
setIsLoaded(true);
|
|
||||||
setError(error);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
fetch("/api/cache")
|
||||||
<div className="container">
|
.then(res => res.json())
|
||||||
<h3 className="my-4 ps-2">Recent messages (3/67)</h3>
|
.then(
|
||||||
<table className="table">
|
(result) => {
|
||||||
<thead>
|
setIsLoaded(true);
|
||||||
<tr>
|
setMessages(result.messages);
|
||||||
<th scope="col">Time</th>
|
setCounts({count: result.count, total: result.total});
|
||||||
<th scope="col">Message</th>
|
},
|
||||||
<th scope="col">Source</th>
|
(error) => {
|
||||||
</tr>
|
setIsLoaded(true);
|
||||||
</thead>
|
setError(error);
|
||||||
<tbody>
|
}
|
||||||
<tr>
|
)
|
||||||
<td>Mar 3, 2021</td>
|
}, []);
|
||||||
<td>Hello there from the frontend</td>
|
|
||||||
<td>Front end</td>
|
if (error){
|
||||||
</tr>
|
return <div className="container">Something went wrong</div>;
|
||||||
<tr>
|
} else if (!isLoaded){
|
||||||
<td>Mar 3, 2021</td>
|
return <div className="container">Loading...</div>;
|
||||||
<td>Hello there from the back end</td>
|
} else {
|
||||||
<td>Back end</td>
|
return (
|
||||||
</tr>
|
<div className="container">
|
||||||
<tr>
|
<h3 className="my-4 ps-2">Recent messages ({counts.count}/{counts.total})</h3>
|
||||||
<td>Mar 3, 2021</td>
|
<table className="table">
|
||||||
<td>This is good!</td>
|
<thead>
|
||||||
<td>Front end</td>
|
<tr>
|
||||||
</tr>
|
<th scope="col">Time</th>
|
||||||
</tbody>
|
<th scope="col">Message</th>
|
||||||
</table>
|
<th scope="col">Source</th>
|
||||||
</div>
|
</tr>
|
||||||
)
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{messages.map(msg => (
|
||||||
|
<tr key={msg.time}>
|
||||||
|
<td>{formatTime(msg.time)}</td>
|
||||||
|
<td>{msg.text}</td>
|
||||||
|
<td>{msg.source}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatTime(timestamp) {
|
||||||
|
const t = new Date(timestamp);
|
||||||
|
const fmt = (t.getDate() == new Date().getDate()) ? "h:mmaaa" : "h:mmaaa, MMM d";
|
||||||
|
return format(t, fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Messages;
|
export default Messages;
|
||||||
|
Reference in New Issue
Block a user