Finish merge

This commit is contained in:
agatha 2024-04-09 17:43:06 -04:00
commit b0027575b6
17 changed files with 271 additions and 0 deletions

View File

@ -1,4 +1,5 @@
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import models import models
from database import engine from database import engine
@ -6,6 +7,14 @@ from routers import auth, forum
app = FastAPI() app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=['*'],
allow_credentials=False,
allow_methods=['GET', 'POST'],
allow_headers=['*']
)
models.Base.metadata.create_all(bind=engine) models.Base.metadata.create_all(bind=engine)
app.include_router(forum.router) app.include_router(forum.router)

View File

@ -4,6 +4,16 @@ services:
build: build:
context: ./backend context: ./backend
dockerfile: Dockerfile dockerfile: Dockerfile
ports:
- '8001:8000'
restart: unless-stopped
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports: ports:
- '8000:8000' - '8000:8000'
restart: unless-stopped restart: unless-stopped
depends_on:
- backend

1
frontend/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.idea/

13
frontend/Dockerfile Normal file
View File

@ -0,0 +1,13 @@
FROM node:alpine
WORKDIR /app
COPY ./app/package.json /app/package.json
RUN npm install
COPY ./app /app
RUN npm run build
RUN npm install -g serve
EXPOSE 3000
CMD ["serve", "-s", "--no-clipboard", "build"]

23
frontend/app/.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

40
frontend/app/package.json Normal file
View File

@ -0,0 +1,40 @@
{
"name": "forum",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.6.8",
"bulma": "^1.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

41
frontend/app/src/App.js Normal file
View File

@ -0,0 +1,41 @@
import 'bulma/css/bulma.css'
import {useEffect, useState} from "react";
import axios from "axios";
import PostList from "./components/Post/PostList";
function App() {
const [postList, setPostsList] = useState([]);
const fetchPosts = async () => {
await axios.get("http://localhost:8000/catalog")
.then((response) => { setPostsList(response.data)})
}
useEffect(() => {
fetchPosts();
}, []);
async function handleClickRefresh() {
await fetchPosts();
}
return (
<>
<div className="container">
<section className="hero is-info">
<div className="hero-body">
<p className="title">Singleboard Forum App</p>
</div>
</section>
<div className="section">
<div className="container" style={{marginBottom: "50px"}}>
<button className="button" onClick={handleClickRefresh}>Refresh Posts</button>
</div>
<PostList posts={postList}/>
</div>
</div>
</>
);
}
export default App;

View File

@ -0,0 +1,19 @@
import PostShow from "./PostShow";
function PostList({posts}) {
const renderedPosts = posts.map((post, key) => {
return <PostShow title={post.title} content={post.content} key={key}/>
})
return (
<>
<div className="container">
<div className="columns is-multiline">
{renderedPosts}
</div>
</div>
</>
);
}
export default PostList

View File

@ -0,0 +1,14 @@
function PostShow({title, content, post_id}) {
return (
<>
<div className="column is-4">
<h1 className="is-size-5 has-text-weight-bold">{title}</h1>
<p>{content}</p>
<br />
<p className="is-italic">0 replies</p>
</div>
</>
);
}
export default PostShow;

View File

@ -0,0 +1,8 @@
import React from "react";
import ReactDOM from "react-dom/client"
import App from "./App";
const el = document.getElementById("root");
const root = ReactDOM.createRoot(el)
root.render(<App />)

22
frontend/conf/nginx.conf Normal file
View File

@ -0,0 +1,22 @@
events {
worker_connections 1024;
}
http {
server {
listen 8000 default_server;
listen [::]:8000 default_server;
root /app;
index index.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location /api {
proxy_pass http://backend:8000/;
}
}
}