Skip to content

Commit

Permalink
Feature/#255 - 주식 상세 데이터를 렌더링 (#265)
Browse files Browse the repository at this point in the history
  • Loading branch information
baegyeong authored Nov 27, 2024
2 parents 66bbbe8 + 103e807 commit 30ea3dd
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 85 deletions.
2 changes: 1 addition & 1 deletion packages/frontend/src/apis/queries/stock-detail/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const GetStockResponseSchema = z.object({
marketCap: z.number(),
name: z.string(),
eps: z.number(),
per: z.number(),
per: z.string(),
high52w: z.number(),
low52w: z.number(),
});
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/apis/queries/stocks/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export type GetStockListResponse = z.infer<typeof GetStockListResponseSchema>;
export const StockTimeSeriesRequestSchema = z.object({
stockId: z.string(),
lastStartTime: z.string().datetime().optional(),
timeUnit: z.enum(['day', 'week', 'month', 'year']),
timeunit: z.enum(['day', 'week', 'month', 'year']),
});

export type StockTimeSeriesRequest = z.infer<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,24 @@ import { get } from '@/apis/utils/get';
const getStocksPriceSeries = ({
stockId,
lastStartTime,
timeUnit,
timeunit,
}: StockTimeSeriesRequest) =>
get<StockTimeSeriesResponse>({
schema: StockTimeSeriesResponseSchema,
url: `/api/stock/${stockId}`,
params: {
lastStartTime,
timeUnit,
timeunit,
},
});

export const useGetStocksPriceSeries = ({
stockId,
lastStartTime,
timeUnit,
timeunit,
}: StockTimeSeriesRequest) => {
return useQuery({
queryKey: ['stocksTimeSeries', stockId, lastStartTime, timeUnit],
queryFn: () => getStocksPriceSeries({ stockId, lastStartTime, timeUnit }),
queryKey: ['stocksTimeSeries', stockId, lastStartTime, timeunit],
queryFn: () => getStocksPriceSeries({ stockId, lastStartTime, timeunit }),
});
};
34 changes: 0 additions & 34 deletions packages/frontend/src/constants/METRIC_DETAILS.ts

This file was deleted.

88 changes: 88 additions & 0 deletions packages/frontend/src/constants/metricDetail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { type StockMetricsPanelProps } from '@/types/metrics';

export const METRIC_DETAILS = {
price: {
currentPrice: {
name: '현재가',
message: '현재 주식의 거래 가격이에요.',
},
tradingVolume: {
name: '거래량',
message: '해당 기간 동안 거래된 주식의 수량이에요.',
},
fluctuationRate: {
name: '변동률',
message: '전일 대비 주가 변동 비율이에요.',
},
fiftyTwoWeekRange: {
name: '52주 최고/최저가',
message: '최근 52주 동안의 최고/최저 주가예요.',
},
},
enterpriseValue: {
marketCap: {
name: '시가총액',
message: '발행 주식 수와 현재 가격을 곱한 값으로, 기업가치를 나타내요.',
},
per: {
name: 'PER',
message: '주가/주당순이익으로, 주식의 투자 매력도를 나타내요.',
},
eps: {
name: 'EPS',
message: '주당순이익으로, 기업의 수익성을 보여줘요.',
},
},
};

export const METRICS_DATA = ({
price,
volume,
change,
high52w,
low52w,
marketCap,
per,
eps,
}: StockMetricsPanelProps) => {
return {
price: {
title: '가격',
metrics: [
{
...METRIC_DETAILS.price.currentPrice,
value: price?.toLocaleString(),
},
{
...METRIC_DETAILS.price.tradingVolume,
value: volume?.toLocaleString(),
},
{
...METRIC_DETAILS.price.fluctuationRate,
value: change?.toLocaleString(),
},
{
...METRIC_DETAILS.price.fiftyTwoWeekRange,
value: `${high52w?.toLocaleString()}/${low52w?.toLocaleString()}`,
},
],
},
enterpriseValue: {
title: '기업가치',
metrics: [
{
...METRIC_DETAILS.enterpriseValue.marketCap,
value: marketCap?.toLocaleString(),
},
{
...METRIC_DETAILS.enterpriseValue.per,
value: per?.toLocaleString(),
},
{
...METRIC_DETAILS.enterpriseValue.eps,
value: eps?.toLocaleString(),
},
],
},
};
};
9 changes: 8 additions & 1 deletion packages/frontend/src/pages/stock-detail/StockDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useGetStockDetail } from '@/apis/queries/stock-detail';
export const StockDetail = () => {
const { stockId } = useParams();
const { data: stockDetail } = useGetStockDetail({ stockId: stockId ?? '' });
const { eps, high52w, low52w, marketCap, per } = stockDetail || {};

return (
<div className="flex h-full flex-col gap-7">
Expand All @@ -24,7 +25,13 @@ export const StockDetail = () => {
<div className="relative h-full">
<TradingChart />
</div>
<StockMetricsPanel />
<StockMetricsPanel
eps={eps}
high52w={high52w}
low52w={low52w}
marketCap={marketCap}
per={per}
/>
</section>
<ChatPanel />
<section className="flex flex-col">
Expand Down
50 changes: 39 additions & 11 deletions packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,45 @@
import { MetricSection } from './components';
import { METRIC_DETAILS } from '@/constants/METRIC_DETAILS';
import { MetricItem, Title } from './components';
import { METRICS_DATA } from '@/constants/metricDetail';
import { type StockMetricsPanelProps } from '@/types/metrics';

export const StockMetricsPanel = ({
eps,
high52w,
low52w,
marketCap,
per,
price,
change,
volume,
}: StockMetricsPanelProps) => {
const metricsData = METRICS_DATA({
eps,
high52w,
low52w,
marketCap,
per,
price,
change,
volume,
});

export const StockMetricsPanel = () => {
return (
<article className="flex flex-col gap-10 rounded-md bg-white p-6 shadow">
<MetricSection
title="가격"
metricInfo={Object.values(METRIC_DETAILS.price)}
/>
<MetricSection
title="기업가치"
metricInfo={Object.values(METRIC_DETAILS.enterpriseValue)}
/>
{Object.values(metricsData).map((section) => (
<section className="flex flex-col">
<Title>{section.title}</Title>
<section className="grid grid-cols-[repeat(4,100px)] items-center">
{section.metrics.map((metric) => (
<MetricItem
key={metric.name}
label={metric.name}
value={metric.value}
tooltip={metric.message}
/>
))}
</section>
</section>
))}
</article>
);
};
12 changes: 6 additions & 6 deletions packages/frontend/src/pages/stock-detail/TradingChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ interface TradingChartProps {

export const TradingChart = ({ theme = lightTheme }: TradingChartProps) => {
const { stockId } = useParams();
const [timeUnit, setTimeUnit] =
useState<StockTimeSeriesRequest['timeUnit']>('day');
const [timeunit, setTimeunit] =
useState<StockTimeSeriesRequest['timeunit']>('day');
const containerRef = useRef<HTMLDivElement>(null);

const { data } = useGetStocksPriceSeries({
stockId: stockId ?? '',
timeUnit,
timeunit,
});

const chart = useChart({
Expand All @@ -41,9 +41,9 @@ export const TradingChart = ({ theme = lightTheme }: TradingChartProps) => {
<RadioButton
key={option.id}
id={option.time}
name="timeUnit"
selected={timeUnit === option.time}
onChange={() => setTimeUnit(option.time)}
name="timeunit"
selected={timeunit === option.time}
onChange={() => setTimeunit(option.time)}
>
{option.label}
</RadioButton>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { Tooltip } from '@/components/ui/tooltip';

export interface MetricItemProps {
name: string;
message: string;
label: string;
tooltip: string;
value?: string | number;
}

export const MetricItem = ({ name, message }: MetricItemProps) => {
export const MetricItem = ({ label, tooltip, value }: MetricItemProps) => {
return (
<>
<div className="group relative">
<Tooltip className="absolute bottom-full mb-6">{message}</Tooltip>
<Tooltip className="absolute bottom-full mb-6">{tooltip}</Tooltip>
<span className="display-medium14 text-gray cursor-pointer font-bold">
{name}
{label}
</span>
</div>
<span className="display-medium14 text-dark-gray">00.000</span>
<span className="display-medium14 text-dark-gray">{value}</span>
</>
);
};

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export * from './TextArea';
export * from './MetricItem';
export * from './MetricSection';
export * from './Title';
export * from './StockDetailHeader';
10 changes: 10 additions & 0 deletions packages/frontend/src/types/metrics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export interface StockMetricsPanelProps {
eps?: number;
high52w?: number;
low52w?: number;
marketCap?: number;
per?: string;
price?: number;
change?: number;
volume?: number;
}

0 comments on commit 30ea3dd

Please sign in to comment.