Skip to content

Commit

Permalink
feat: fetch zabo from api server
Browse files Browse the repository at this point in the history
  • Loading branch information
jinho-choi123 committed Oct 28, 2023
1 parent 0de6771 commit 0aa5403
Show file tree
Hide file tree
Showing 17 changed files with 242 additions and 96 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
API_SERVER_URL=
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"plugins": ["import", "@typescript-eslint", "react"],
"ignorePatterns": ["node_modules/", "dist/"],
"rules": {
"no-await-in-loop": "off",
"no-console": "off",
"import/extensions": [
"error",
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.env
# Logs
logs
*.log
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
"@react-spring/web": "^9.7.3",
"@reduxjs/toolkit": "^1.9.7",
"axios": "^1.5.1",
"dayjs": "^1.11.10",
"dotenv": "^16.3.1",
"dotenv-expand": "^10.0.0",
"envsafe": "^2.0.3",
"http-proxy-middleware": "^2.0.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-qr-code": "^2.0.12",
Expand Down
7 changes: 4 additions & 3 deletions src/components/Board/Board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const Board = () => {
<main className={style.board}>
<Logo />
{zaboList.map((zabo: ZaboJson) => (
<div key={zabo.imageUrl}>
<div key={`${zabo.imageUrl}div`}>
<Background
key={`${zabo.imageUrl}back`}
imageUrl={zabo.imageUrl}
Expand All @@ -44,8 +44,9 @@ export const Board = () => {
<Info
key={`${zabo.imageUrl}info`}
title={zabo.title}
description={zabo.description}
date={zabo.date}
owner={zabo.owner}
scheduleDate={zabo.scheduleDate}
scheduleType={zabo.scheduleType}
state={zabo.state}
/>
<Qr
Expand Down
12 changes: 11 additions & 1 deletion src/components/Info/Info.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,30 @@

.text {
display: flex;

flex-direction: column;
color: $white;
position: absolute;
bottom: 861px;
left: 216px;




h1 {
font-size: 140px;
font-weight: 900;
margin-bottom: 28px;
width: 1323px;
overflow: hidden;
text-overflow: ellipsis;
word-break: keep-all;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3; /* number of lines to show */
}

.description {
.owner {
font-size: 80px;
font-weight: 400;
opacity: 0.6;
Expand Down
18 changes: 12 additions & 6 deletions src/components/Info/Info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { type InfoProps, ZaboState } from "@/types";
import { useSpring, animated } from "@react-spring/web";
import { useEffect } from "react";
import eventBtn from "@/public/eventBtn.svg";
import registrationBtn from "@/public/registrationBtn.svg";
import { infoFadeIn, infoFadeOut } from "./Info.animation";
import style from "./Info.module.scss";

export const Info = (infoProps: InfoProps) => {
const { title, description, date, state } = infoProps;
const { title, owner, scheduleDate, scheduleType, state } = infoProps;

const [springs, api] = useSpring(() => ({
from: {
Expand All @@ -26,11 +27,16 @@ export const Info = (infoProps: InfoProps) => {
return (
<animated.div className={style.text} style={{ ...springs }}>
<h1>{title}</h1>
<p className={style.description}>{description}</p>
<div className={style.date}>
<img src={eventBtn} alt="행사" />
<p>{date}</p>
</div>
{owner !== null ? <p className={style.owner}>by {owner}</p> : null}
{scheduleType !== null ? (
<div className={style.date}>
<img
src={scheduleType === "행사" ? eventBtn : registrationBtn}
alt={scheduleType}
/>
<p>{scheduleDate}</p>
</div>
) : null}
</animated.div>
);
};
4 changes: 2 additions & 2 deletions src/config/animation.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export const AnimationDuration = 3200;
export const TransitionInterval = 10000;
export const AnimationDuration = 2000;
export const TransitionInterval = 4000;
2 changes: 2 additions & 0 deletions src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from "./animation";

export * from "./share";
1 change: 1 addition & 0 deletions src/config/share.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const ZABO_SHARE_BASE_URL = "https://zabo.sparcs.org";
148 changes: 81 additions & 67 deletions src/redux/zabos/fetchZaboThunk.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,87 @@
import axios from "axios";
import dayjs from "dayjs";
import type { AppDispatch } from "@/redux/store";
import { ZaboState } from "@/types";
import { ZaboState, type ZaboJson } from "@/types";
import { ZABO_SHARE_BASE_URL } from "@/config";
import { pushZabos } from "./zaboSlice";

export const fetchZaboThunk = () => async (dispatch: AppDispatch) => {
const currentDate = new Date();
const timestamp = currentDate.getTime();
// attach timestamp to image url to prevent browser cache
// this leads to animation crash
// also prevent duplicate keys of components
const timestamp = new Date().getTime();
const postFix = (idx: number) =>
"".concat("?t=", `${timestamp}`, "&idx=", `${idx}`);

dispatch(
pushZabos([
{
title: "33333333333",
description: "설명",
date: "08.03",
qrUrl: "https://zabo.sparcs.org/s/86f104",
imageUrl: `https://sparcs-kaist-zabo-prod.s3.ap-northeast-2.amazonaws.com/zabo/zabo-136421683085229471?a=${
timestamp + 10
}`,
state: ZaboState.PENDING_STATE,
},
{
title: "444444444444",
description: "다음자보설명",
date: "08.03",
qrUrl: "https://zabo.sparcs.org/s/86f104",
imageUrl: `https://sparcs-kaist-zabo-prod.s3.ap-northeast-2.amazonaws.com/zabo/zabo-136421683085229471?a=${
timestamp + 22
}`,
state: ZaboState.PENDING_STATE,
},
{
title: "555555555555",
description: "다음자보설명",
date: "08.03",
qrUrl: "https://zabo.sparcs.org/s/17e13c",
imageUrl: `https://sparcs-kaist-zabo-prod.s3.ap-northeast-2.amazonaws.com/zabo/zabo-136421683085229471?a=${
timestamp + 33
}`,
state: ZaboState.PENDING_STATE,
},
{
title: "666666",
description: "다음자보설명",
date: "08.03",
qrUrl: "https://zabo.sparcs.org/s/17e13c",
imageUrl: `https://sparcs-kaist-zabo-prod.s3.ap-northeast-2.amazonaws.com/zabo/zabo-136421683085229471?a=${
timestamp + 44
}`,
state: ZaboState.PENDING_STATE,
},
{
title: "777777777",
description: "다음자보설명",
date: "08.03",
qrUrl: "https://zabo.sparcs.org/s/17e13c",
imageUrl: `https://sparcs-kaist-zabo-prod.s3.ap-northeast-2.amazonaws.com/zabo/zabo-136421683085229471?a=${
timestamp + 55
}`,
state: ZaboState.PENDING_STATE,
},
{
title: "888888",
description: "다음자보설명",
date: "08.03",
qrUrl: "https://zabo.sparcs.org/s/17e13c",
imageUrl: `https://sparcs-kaist-zabo-prod.s3.ap-northeast-2.amazonaws.com/zabo/zabo-136421683085229471?a=${
timestamp + 66
}`,
state: ZaboState.PENDING_STATE,
},
]),
);
// fetch zabos from server
// single zabo list get api gets 20 zabos. so we will call it 5 times to fetch total 50 zabos
// we will circulate top 50 zabos
// important thing is that, we have to set lastSeen params to get zabos after lastSeen
// so we can not do 5 requests in parallel. it should be sequential
let zabosData: ZaboJson[] = [];
for (let i = 0; i < 1; i += 1) {
const lastFetched =
zabosData.length > 0 ? zabosData[zabosData.length - 1].id : null;

// fetch zabos based on lastSeen(lastFetched)
const { data } =
lastFetched === null
? await axios.get("/api/zabo/list")
: await axios.get("/api/zabo/list", {
params: {
lastSeen: lastFetched,
},
});

// parse fetched zabos to ZaboJson
// remove unnecessary fields
// add state field
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const parsedZabos = data.map((zabo: any, index: number) => {
const { title, description, likesCount, views, score, effectiveViews } =
zabo;
/* eslint-disable-next-line no-underscore-dangle */
const id = zabo._id;
const likes = likesCount;
const owner = zabo.owner.name;
const scheduleType =
zabo.schedules.length > 0 ? zabo.schedules[0].eventType : null;
const scheduleDate =
zabo.schedules.length > 0
? dayjs(zabo.schedules[0].startAt).format("MM.DD")
: null;
const qrUrl = "".concat(
ZABO_SHARE_BASE_URL,
"/s/",
id.substring(id.length - 6),
);
const imageUrl =
zabo.photos.length > 0 ? zabo.photos[0].url + postFix(index) : null;
const state = ZaboState.PENDING_STATE;

return {
id,
title,
owner,
description,
scheduleType,
scheduleDate,
qrUrl,
imageUrl,
state,
likes,
views,
score,
effectiveViews,
};
});

zabosData = zabosData.concat(parsedZabos);
}

// we have to remove zabos that have no image url
zabosData = zabosData.filter((zabo: ZaboJson) => zabo.imageUrl !== null);
console.log(zabosData);

dispatch(pushZabos(zabosData));
};
36 changes: 25 additions & 11 deletions src/redux/zabos/zaboSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,36 @@ export interface ZaboListState {
const initialState: ZaboListState = {
zaboList: [
{
title: "1111111111",
description: "Z111111111",
date: "08.03",
id: "0000000000000",
title: "ZABO BOARD 2023 LAUNCHING",
owner: "SPARCS",
description: "HELLO WORLD",
scheduleType: null,
scheduleDate: null,
qrUrl: "https://zabo.sparcs.org/s/86f104",
imageUrl:
"https://sparcs-kaist-zabo-prod.s3.ap-northeast-2.amazonaws.com/zabo/zabo-136421683085229471?a=1sdf23tg",
qrUrl: "https://zabo.sparcs.org/s/86f104",
state: ZaboState.CURRENT_STATE,
score: 0,
views: 0,
effectiveViews: 0,
likes: 0,
},
{
title: "2222222222",
description: "Z2222222",
date: "08.03",
imageUrl:
"https://sparcs-kaist-zabo-prod.s3.ap-northeast-2.amazonaws.com/zabo/zabo-136421683085229471?a=1wef3gfwe",
id: "11111111111",
title: "ZABO BOARD 2023 LAUNCHING",
owner: "SPARCS",
description: "HELLO WORLD",
scheduleType: null,
scheduleDate: null,
qrUrl: "https://zabo.sparcs.org/s/86f104",
imageUrl:
"https://sparcs-kaist-zabo-prod.s3.ap-northeast-2.amazonaws.com/zabo/zabo-136421683085229471?a=1sdf23tg",
state: ZaboState.BEFORE_STATE,
score: 0,
views: 0,
effectiveViews: 0,
likes: 0,
},
],
leftoverLength: 0,
Expand All @@ -36,7 +50,7 @@ const zaboSlice = createSlice({
reducers: {
pushZabos: (state, action) => {
// if there are plenty of leftover zabos, we do not dispatch
if (state.leftoverLength > 200) {
if (state.leftoverLength > 10) {
return;
}

Expand All @@ -60,7 +74,7 @@ const zaboSlice = createSlice({
state.leftoverLength += newZaboListLength;
},
moveToNext: state => {
// if there are less than 1 leftover zabos, we do not dispatch
// if there are less than 2 leftover zabos, we do not dispatch
if (state.leftoverLength < 1) {
return;
}
Expand Down
5 changes: 3 additions & 2 deletions src/types/InfoProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import type { ZaboState } from "./ZaboState";

export type InfoProps = {
title: string;
description: string;
date: string;
owner: string;
scheduleType: string | null;
scheduleDate: string | null;
state: ZaboState;
};
9 changes: 8 additions & 1 deletion src/types/ZaboJson.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import type { ZaboState } from "./ZaboState";

export type ZaboJson = {
id: string;
title: string;
owner: string;
description: string;
date: string;
scheduleType: string | null;
scheduleDate: string | null;
qrUrl: string;
imageUrl: string;
state: ZaboState;
score: number;
views: number;
effectiveViews: number;
likes: number;
};
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"noEmit": true,
"jsx": "react-jsx",
},
"include": ["src", "vite.config.ts"],
"include": ["src", "vite.config.ts" ],
"references": [
{
"path": "./tsconfig.node.json"
Expand Down
Loading

0 comments on commit 0aa5403

Please sign in to comment.