Skip to content

Commit

Permalink
88 ssr frontend framework (#89)
Browse files Browse the repository at this point in the history
* update gitignore

* initialize nextjs app

* initial project scaffold

* conditionally use body wrapping (grid)

* rename

* remap prop to better represent data

* fetch serverside props and populate charts

* fetch serverside props and populate charts

* remove hr

* add line chart

* remove season list

* load season list on each page

* populate trends chart

* ensure cap case is correct for all titles

* Change chart title for O_ALL charts

* remove unused components

* Disable workflows (temporarily)

* update dockerignore

* add eslint exclusions

* change endpoints to docker internal names

* rename dockerfile to dockerfile.server

* create nextjs dockerfile

* create testing docker-compose.yml

* change web to server

* change web to server

* fix dependency name

* fix dependency name

* add navbar links

* remove unused data prop

* bun lockfile

* modify header condition

* populate latest season in index page

* add frontend buildable workflow

* remove season 8

* add/modify ghcr labels

* add push logic

* enable workflows

* fix dockerfile reference

* disable tests again

* remove test pass condition (temporary)

* run push on main branch only

* remove server tests (will be re-written)

* revert workflow conditions
  • Loading branch information
thearyadev authored Dec 23, 2023
1 parent 70694a2 commit ddc9f30
Show file tree
Hide file tree
Showing 39 changed files with 932 additions and 250 deletions.
6 changes: 4 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
assets
models
tests
Dockerfile
Dockerfile.server
Dockerfile.frontend
README.md
mypy-t.sh
LICENSE
tmp
tmp
node_modules/
31 changes: 25 additions & 6 deletions .github/workflows/tests_and_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: Tests and CI
on:
pull_request:
push:
branches:
- main

jobs:
tests:
Expand Down Expand Up @@ -51,22 +53,39 @@ jobs:
TESTING_MYSQLHOST: 'localhost'
TESTING_MYSQLPORT: '3800'

docker-buildable:
docker-server-buildable:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build the image
- name: Build the server image
run: |
docker build . --tag ghcr.io/thearyadev/top500-aggregator:latest
docker build . --tag ghcr.io/thearyadev/top500-aggregator-server:latest --file ./Dockerfile.server
docker-frontend-buildable:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build the frontend image
run: |
docker build . --tag ghcr.io/thearyadev/top500-aggregator-frontend:latest --file ./Dockerfile.frontend

build_and_publish:
runs-on: ubuntu-latest
needs: tests
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Build and push the image
- name: Docker Login
run: |
docker login --username thearyadev --password ${{ secrets.GH_PAT }} ghcr.io
docker build . --tag ghcr.io/thearyadev/top500-aggregator:latest
docker push ghcr.io/thearyadev/top500-aggregator:latest
- name: Build Frontend
run: |
docker build . --tag ghcr.io/thearyadev/top500-aggregator-frontend:latest --file ./Dockerfile.frontend
- name: Build Server
run: |
docker build . --tag ghcr.io/thearyadev/top500-aggregator-server:latest --file ./Dockerfile.server
- name: push images
run: |
docker push ghcr.io/thearyadev/top500-aggregator-frontend:latest
docker push ghcr.io/thearyadev/top500-aggregator-server:latest
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ temp
.env
.bashrc
.idea
tmp
tmp
node_modules/
36 changes: 36 additions & 0 deletions Dockerfile.frontend
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Install dependencies only when needed
FROM node:lts-alpine as deps
LABEL org.opencontainers.image.source=https://github.com/thearyadev/top500-aggregator
LABEL org.opencontainers.image.description="Docker image for t500 aggregator frontend"
LABEL org.opencontainers.image.licenses=MIT
WORKDIR /opt/app
COPY frontend/package.json /frontend/bun.lockb ./
RUN npm install

# Rebuild the source code only when needed
# This is where because may be the case that you would try
# to build the app based on some `X_TAG` in my case (Git commit hash)
# but the code hasn't changed.
FROM node:lts-alpine as builder


ENV NODE_ENV=production
WORKDIR /opt/app

COPY frontend .
RUN ls -la
COPY --from=deps /opt/app/node_modules ./node_modules
RUN npm run build

# Production image, copy all the files and run next
FROM node:lts-alpine as runner


ARG X_TAG
WORKDIR /opt/app
ENV NODE_ENV=production
COPY --from=builder /opt/app/next.config.js ./
COPY --from=builder /opt/app/public ./public
COPY --from=builder /opt/app/.next ./.next
COPY --from=builder /opt/app/node_modules ./node_modules
CMD ["node_modules/.bin/next", "start"]
2 changes: 1 addition & 1 deletion Dockerfile → Dockerfile.server
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ WORKDIR /t500-aggregator
COPY . .

LABEL org.opencontainers.image.source=https://github.com/thearyadev/top500-aggregator
LABEL org.opencontainers.image.description="Docker image for t500 aggregator"
LABEL org.opencontainers.image.description="Docker image for t500 aggregator server"
LABEL org.opencontainers.image.licenses=MIT

RUN pip install poetry==1.6.1 && poetry install --with server --without dev
Expand Down
42 changes: 42 additions & 0 deletions docker-compose.test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
version: "3.9"
services:
nginx:
image: nginx:latest
depends_on:
- server
volumes:
- "./nginx.conf:/etc/nginx/nginx.conf"
ports:
- "7779:80"

server: # port 8000 is server
build:
dockerfile: Dockerfile.server
environment:
MYSQLDATABASE: 'railway'
MYSQLUSER: 'root'
MYSQLPASSWORD: 'QiyWsI7y1oGGJjz4biiu'
MYSQLHOST: 'database'
MYSQLPORT: '3306'
depends_on:
- database

frontend:
build:
dockerfile: Dockerfile.frontend
ports:
- "3000:3000"


# these services are internal, so secrets do not matter.
database:
image: mysql@sha256:566007208a3f1cc8f9df6b767665b5c9b800fc4fb5f863d17aa1df362880ed04
environment:
MYSQL_DATABASE: 'railway'
MYSQL_USER: 't5aggr'
MYSQL_PASSWORD: 'QiyWsI7y1oGGJjz4biiu'
MYSQL_ROOT_PASSWORD: 'QiyWsI7y1oGGJjz4biiu'
volumes:
- ./mysql-data:/var/lib/mysql
ports:
- "3309:3306"
16 changes: 9 additions & 7 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ services:
nginx:
image: nginx:latest
depends_on:
- web
- server
volumes:
- "./nginx.conf:/etc/nginx/nginx.conf"
ports:
- "7777:80"

web: # port 8000 is server
server: # port 8000 is server

image: ghcr.io/thearyadev/top500-aggregator:latest
# build: .
Expand All @@ -21,7 +21,12 @@ services:
MYSQLPORT: '3306'
depends_on:
- database


frontend:
build:
dockerfile: Dockerfile.frontend
ports:
- "3000:3000"
# these services are internal, so secrets do not matter.
database:
image: mysql@sha256:566007208a3f1cc8f9df6b767665b5c9b800fc4fb5f863d17aa1df362880ed04
Expand All @@ -31,7 +36,4 @@ services:
MYSQL_PASSWORD: 'QiyWsI7y1oGGJjz4biiu'
MYSQL_ROOT_PASSWORD: 'QiyWsI7y1oGGJjz4biiu'
volumes:
- ./mysql-data:/var/lib/mysql
# ports:
# - "3306:3306"

- ./mysql-data:/var/lib/mysql
7 changes: 7 additions & 0 deletions frontend/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "next/core-web-vitals",
"rules": {
"react/jsx-key": "off",
"react/no-unescaped-entities": "off"
}
}
36 changes: 36 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
22 changes: 22 additions & 0 deletions frontend/app/components/card/card.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.card {
@apply border-2;
@apply p-3;
@apply rounded;
@apply mb-3
}

.heading-container {
}

.title{
@apply text-lg;
@apply font-bold
}

.subtitle{
@apply font-extralight
}

.cardBodyWrap {
@apply grid grid-cols-1 md:grid-cols-3 gap-4;
}
18 changes: 18 additions & 0 deletions frontend/app/components/card/card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import styles from "./card.module.scss"


const Card = ({children, title, subtitle, nowrap}: { children: React.ReactNode, title: string, subtitle?: string, nowrap?:boolean }) => {
return (
<div className={styles.card}>
<div className={styles.headingContainer}>
<h3 className={styles.title}>{title}</h3>
{subtitle ? <h4 className={styles.subtitle}>{subtitle}</h4> : null}
</div>
<div className={ nowrap ? undefined : styles.cardBodyWrap}>
{children}
</div>
</div>
)
}

export default Card;
6 changes: 6 additions & 0 deletions frontend/app/components/charts/barChart.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.chartContainer {
.highcharts-title{
display: none;

}
}
70 changes: 70 additions & 0 deletions frontend/app/components/charts/barChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import * as Highcharts from 'highcharts';
import HighchartsReact from "highcharts-react-official";
import {useRef} from "react";
import styles from "./barChart.module.scss"
import {HeroColors} from "@/app/components/charts/heroColors";

interface GraphData {
labels: string[]
values: number[]
}

interface BarChartProps extends HighchartsReact.Props {
title: string;
graph: GraphData
maxY: number;
}


const BarChart = (props: BarChartProps) => {
const {title, graph, maxY} = props;
const options: Highcharts.Options = {
title: {
// @ts-ignore
text: null,
margin: 0,
},
legend: {
enabled: false,
},
xAxis: {
categories: graph.labels,
},
series: [{
type: 'column',
name: "Occurrences",
data: graph.values.map((item, index) => {
return {y: item, color: HeroColors[graph.labels[index]]} // do lookup
})
}],
credits: {
enabled: false,
},
yAxis: {
min: 0,
max: maxY,
title: {
text: null,
},
}
};
const chartComponentRef = useRef<HighchartsReact.RefObject>(null)

return (
<div className={styles.chartContainer}>
<h5 className="text-center pb-2 capitalize">{title.toLowerCase()}</h5>
<HighchartsReact
id="gnomegnome"
highcharts={Highcharts}
options={options}
ref={chartComponentRef}
{...props}
/>

</div>

)

}

export default BarChart;
Loading

0 comments on commit ddc9f30

Please sign in to comment.