Skip to content

Commit 6064e79

Browse files
committed
feat: add db connection to http
1 parent d6ba569 commit 6064e79

File tree

19 files changed

+214
-42
lines changed

19 files changed

+214
-42
lines changed

frontend/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
<!DOCTYPE html>
1+
<!doctype html>
22
<html lang="en" class="light">
33
<head>
44
<meta charset="UTF-8" />
55
<link rel="icon" type="image/x-icon" href="/react.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>Instructor</title>
8+
<link href="/src/global.css" rel="stylesheet" />
89
</head>
910
<body>
1011
<div id="root"></div>

frontend/lib/http.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import axios from "axios";
2+
3+
export const client = axios.create({
4+
method: "GET",
5+
baseURL: "http://localhost:3333",
6+
headers: { "Access-Control-Allow-Origin": "*" },
7+
});

frontend/src/app/error.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { ErrorBoundary as ReactErrorBoundary } from "react-error-boundary";
2+
3+
function ErrorDisplay({
4+
error = Error("Unknown"),
5+
}: {
6+
error?: Error;
7+
resetErrorBoundary?: () => void;
8+
}) {
9+
return (
10+
<div role="alert">
11+
<p>Something went wrong:</p>
12+
<pre style={{ color: "red" }}>{error.message}</pre>
13+
</div>
14+
);
15+
}
16+
17+
export const ErrorBoundary = ({ children }: { children?: React.ReactNode }) => {
18+
return (
19+
<ReactErrorBoundary fallbackRender={ErrorDisplay}>
20+
{children}
21+
</ReactErrorBoundary>
22+
);
23+
};

frontend/src/app/index.tsx

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { Suspense, useMemo } from "react";
1+
import { useMemo } from "react";
22
import { createRoot } from "react-dom/client";
33
import { createBrowserRouter, RouterProvider } from "react-router-dom";
4-
import { ErrorBoundary } from "react-error-boundary";
54
import {
65
useQueryClient,
76
QueryClient,
@@ -12,32 +11,30 @@ import { defaultOptions } from "@/config/query";
1211
import router from "./router";
1312
import Layout from "./layout";
1413
import "../global.css";
14+
import { ErrorBoundary } from "./error";
1515

1616
const root = document.getElementById("root");
1717

1818
if (!root) {
1919
throw new Error("No root element found to hydrate app!");
2020
}
2121

22-
const AppError = () => {
23-
return <span>Error!</span>;
24-
};
25-
2622
const App = () => {
2723
const queryClient = useQueryClient(new QueryClient(defaultOptions));
28-
const memoRouter = useMemo(() => createBrowserRouter(router), [queryClient]);
24+
25+
const memoRouter = useMemo(() => {
26+
return createBrowserRouter(router, {});
27+
}, [queryClient]);
2928

3029
return (
31-
<QueryClientProvider client={queryClient}>
32-
{import.meta.env.DEV && <ReactQueryDevtools />}
33-
<Layout>
34-
<Suspense fallback={null}>
35-
<ErrorBoundary FallbackComponent={AppError}>
36-
<RouterProvider router={memoRouter} />;
37-
</ErrorBoundary>
38-
</Suspense>
39-
</Layout>
40-
</QueryClientProvider>
30+
<ErrorBoundary>
31+
<QueryClientProvider client={queryClient}>
32+
{import.meta.env.DEV && <ReactQueryDevtools />}
33+
<Layout>
34+
<RouterProvider router={memoRouter} />
35+
</Layout>
36+
</QueryClientProvider>
37+
</ErrorBoundary>
4138
);
4239
};
4340

frontend/src/app/layout.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
export type AppLayoutProps = {
1+
export type LayoutProps = {
22
children: React.ReactNode;
33
};
44

5-
export default function AppLayout({ children }: AppLayoutProps) {
5+
export default function Layout({ children }: LayoutProps) {
66
return (
77
<div className="mx-auto flex min-h-screen w-screen max-w-screen-2xl flex-col p-2 font-family-[Gotham]">
88
<div
9-
className={`relative flex w-full rounded-2xl bg-white-4 dark:bg-dark `}
9+
className={`relative flex w-full rounded-2xl bg-white-4 dark:bg-dark`}
1010
>
1111
&nbsp;
1212
</div>
1313
<div className="mt-2 flex w-full flex-1 gap-2 rounded-2xl">
1414
<main className="h-fit w-full rounded-2xl bg-white-3 dark:bg-dark-2">
15-
<img src="/logo.gif" alt="Instructor Logo" />
1615
{children}
1716
</main>
1817
</div>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { use } from "react";
2+
import { client } from "../../../lib/http";
3+
4+
const promise = client.get("/");
5+
6+
export default function Component() {
7+
const result = use(promise);
8+
return <div>{JSON.stringify(result)}</div>;
9+
}

frontend/src/app/product/index.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
// if (import.meta.env.SSR) {
2-
// ... server only logic
3-
// }
1+
"use client";
2+
3+
import { Suspense } from "react";
4+
import Component from "./component";
45

56
function Product() {
6-
return <div className="flex flex-col">Product</div>;
7+
return (
8+
<Suspense>
9+
<Component />
10+
</Suspense>
11+
);
712
}
813

914
export default Product;

frontend/src/app/router.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
import Product from "@/app/product";
22
import Splash from "@/app/splash";
3+
import { IndexRouteObject } from "react-router";
4+
import { ErrorBoundary } from "./error";
35

4-
const router = [
6+
const router: IndexRouteObject[] = [
57
{
8+
index: true,
69
path: "/",
710
element: <Splash />,
11+
ErrorBoundary: ErrorBoundary,
812
},
913
{
14+
index: true,
1015
path: "/product",
1116
element: <Product />,
17+
ErrorBoundary: ErrorBoundary,
1218
},
1319
];
1420

frontend/src/global.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
@import "tailwindcss";
12
@import "./fonts.css";
3+
@import "tailwind/preflight";
24

3-
@tailwind base;
4-
@tailwind components;
55
@tailwind utilities;
66

77
@layer base {

http/cmd/api-server/main.go

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"database/sql"
55
"fmt"
66
"github.com/labstack/echo/v4"
7+
"github.com/labstack/echo/v4/middleware"
78
"net/http"
89
"os"
910

@@ -20,29 +21,53 @@ const (
2021

2122
func main() {
2223
e := echo.New()
24+
e.Use(middleware.Logger())
25+
e.Use(middleware.Recover())
26+
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
27+
AllowOrigins: []string{"http://localhost:3003"},
28+
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
29+
}))
2330

24-
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
31+
e.OPTIONS("/*", func(c echo.Context) error {
32+
return c.NoContent(http.StatusOK)
33+
})
34+
35+
e.GET("/", func(c echo.Context) error {
36+
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
2537
"password=%s dbname=%s sslmode=disable",
2638
host, port, user, password, dbname)
2739

28-
db, err := sql.Open("postgres", psqlInfo)
29-
if err != nil {
30-
panic(err)
31-
}
40+
db, err := sql.Open("postgres", psqlInfo)
3241

33-
defer func() {
34-
if cerr := db.Close(); cerr != nil {
35-
fmt.Printf("error closing DB: %v\n", cerr)
42+
if err != nil {
43+
panic(err)
3644
}
37-
}()
3845

39-
e.GET("/", func(c echo.Context) error {
40-
return c.String(http.StatusOK, "ok")
46+
rows, err := db.Query("SELECT id, name FROM users")
47+
48+
if err != nil {
49+
panic(err)
50+
}
51+
52+
defer func() {
53+
if cerr := rows.Close(); cerr != nil {
54+
fmt.Printf("error closing DB: %v\n", cerr)
55+
}
56+
}()
57+
58+
defer func() {
59+
if cerr := db.Close(); cerr != nil {
60+
fmt.Printf("error closing DB: %v\n", cerr)
61+
}
62+
}()
63+
64+
return c.JSON(http.StatusOK, rows)
4165
})
4266

4367
e.GET("/manifest", func(c echo.Context) error {
4468
return c.String(http.StatusOK, "ok")
4569
})
4670

71+
4772
e.Logger.Fatal(e.Start(":" + os.Getenv("HTTP_PORT")))
4873
}

0 commit comments

Comments
 (0)