127 lines
2.9 KiB
TypeScript
127 lines
2.9 KiB
TypeScript
import { Button } from "../components/Button.tsx";
|
|
import { useEffect } from "preact/hooks";
|
|
import { ComponentChildren } from "preact";
|
|
import { Signal, useSignal } from "@preact/signals";
|
|
|
|
interface StockProps {
|
|
pageName: string;
|
|
}
|
|
|
|
interface ToggleButtonProps {
|
|
children?: ComponentChildren;
|
|
}
|
|
|
|
function ToggleButton(props: ToggleButtonProps) {
|
|
return (
|
|
<Button {...props}>
|
|
</Button>
|
|
);
|
|
}
|
|
|
|
type QueryStatus<T> = {
|
|
type: "loading";
|
|
} | {
|
|
type: "complete";
|
|
data: T;
|
|
} | {
|
|
type: "error";
|
|
err: Error;
|
|
};
|
|
|
|
const cacheMap = new Map<string, unknown>();
|
|
function useQuery<T>(url: string): Signal<QueryStatus<T>> {
|
|
const state = useSignal({
|
|
type: "loading",
|
|
} as QueryStatus<T>);
|
|
useEffect(() => {
|
|
if (!cacheMap.has(url)) {
|
|
(async () => {
|
|
try {
|
|
const res = await fetch(url);
|
|
const data = await res.json();
|
|
cacheMap.set(url, data);
|
|
state.value = {
|
|
type: "complete",
|
|
data: data,
|
|
};
|
|
} catch (err) {
|
|
state.value = {
|
|
type: "error",
|
|
err: err,
|
|
};
|
|
}
|
|
})();
|
|
} else {
|
|
state.value = {
|
|
type: "complete",
|
|
data: cacheMap.get(url) as T,
|
|
};
|
|
}
|
|
},[]);
|
|
return state;
|
|
}
|
|
|
|
interface Coperation {
|
|
Name: string;
|
|
Code: string;
|
|
Sector: string;
|
|
Product: string;
|
|
ListingDay: string;
|
|
ClosingMonth: string;
|
|
Representative: string;
|
|
Homepage: string;
|
|
AddressArea: string;
|
|
LastUpdate: string;
|
|
}
|
|
|
|
interface PageCorpsInfo {
|
|
name: string;
|
|
description: string;
|
|
corpListByDate: Record<string, Coperation[]>;
|
|
}
|
|
|
|
function StockList({data}: {data: PageCorpsInfo}){
|
|
console.log("data")
|
|
const keys = Object.keys(data.corpListByDate).sort().reverse().slice(0,5).reverse();
|
|
//const rows = data.corpListbyDate;
|
|
|
|
return <div class="flex">
|
|
{keys.map((x,i)=>{
|
|
const rows = data.corpListByDate[x];
|
|
return <div key={x}>
|
|
{rows.map(row=>{
|
|
return <div>
|
|
{row.Name}
|
|
</div>
|
|
})}
|
|
</div>
|
|
})}
|
|
</div>
|
|
}
|
|
|
|
export default function StockListUI(props: StockProps) {
|
|
const sig = useQuery<PageCorpsInfo>("/api/pages/" + props.pageName);
|
|
return (
|
|
<div class="my-2">
|
|
<div class="flex gap-2">
|
|
<ToggleButton>Kospi</ToggleButton>
|
|
<ToggleButton>Kosdaq</ToggleButton>
|
|
<ToggleButton>Otherwise</ToggleButton>
|
|
</div>
|
|
<div class="flex gap-8 py-6 flex-col">
|
|
{sig.value.type == "loading"
|
|
? (new Array(20).fill(0).map((_) => (
|
|
<div class="animate-pulse bg-gray-300 p-2"></div>
|
|
)))
|
|
: <div>
|
|
{
|
|
sig.value.type == "error" ? (<div>
|
|
<p>File Loading Failed</p>
|
|
</div>) : <StockList data={sig.value.data}></StockList>
|
|
}
|
|
</div>}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|