Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 1 addition & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions src/apis/banner/bannerApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import instance from '../axios/instance';

export interface BannerApiResponse {
Bitcoin: 'RISE,' | 'DECLINE,' | 'STABLE';
Ethereum: 'RISE,' | 'DECLINE,' | 'STABLE';
Solana: 'RISE,' | 'DECLINE,' | 'STABLE';
}

export interface TransformedBannerData {
value: string;
status: 'RISE,' | 'DECLINE,' | 'STABLE';
}

const bannerApi = async (): Promise<TransformedBannerData[]> => {
const response = await instance.get<BannerApiResponse>(
`api/emotional-index/change-directions`,
);

const data = response.data;

return Object.entries(data).map(([key, value]) => ({
value: key,
status: value,
}));
};

export default bannerApi;
23 changes: 23 additions & 0 deletions src/apis/chart/chartApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import instance from '../axios/instance';

export interface chartApiProps {
type?: 'ALL' | 'Bitcoin' | 'Ethereum' | 'Solana';
}

export interface ChartDataPoint {
time: string;
Bitcoin?: number;
Ethereum?: number;
Solana?: number;
}

const chartApi = async ({ type = 'ALL' }: chartApiProps = {}): Promise<
ChartDataPoint[]
> => {
const response = await instance.get<ChartDataPoint[]>(`api/emotional-index`, {
params: { type },
});
return response.data;
};

export default chartApi;
Binary file added src/assets/banner/stable.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions src/hooks/useQuery/useGetBannerData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
import bannerApi, {
type TransformedBannerData,
} from '../../apis/banner/bannerApi';

const QUERY_KEYS = {
bannerData: ['bannerData'] as const,
};

function useGetBannerData(): UseQueryResult<TransformedBannerData[], Error> {
return useQuery<TransformedBannerData[], Error>({
queryKey: ['bannerData'],
queryFn: bannerApi,
staleTime: 1 * 60 * 1000,
refetchInterval: 1 * 60 * 1000,
refetchIntervalInBackground: true,
});
}

export default useGetBannerData;
export { QUERY_KEYS };
27 changes: 27 additions & 0 deletions src/hooks/useQuery/useGetChartData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
import chartApi, {
type chartApiProps,
type ChartDataPoint,
} from '../../apis/chart/chartApi';

interface UseGetChartDataProps {
type?: chartApiProps['type'];
enabled?: boolean;
}

function useGetChartData({
type = 'ALL',
enabled = true,
}: UseGetChartDataProps = {}): UseQueryResult<ChartDataPoint[], Error> {
return useQuery<ChartDataPoint[], Error>({
queryKey: ['chartData', type],
queryFn: () => chartApi({ type }),
enabled,
staleTime: 1 * 60 * 1000,
gcTime: 5 * 60 * 1000,
refetchOnWindowFocus: true,
retry: 2,
});
}

export default useGetChartData;
50 changes: 40 additions & 10 deletions src/pages/home/components/Banner/Banner.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,49 @@
import bannerLogo from '../../../../assets/banner/banner.png';
import up from '../../../../assets/banner/up.png';
import down from '../../../../assets/banner/down.png';
import stable from '../../../../assets/banner/stable.png';
import { motion } from 'framer-motion';

const stocks = [
{ value: 'Bitcoin', status: 'up' },
{ value: 'Ethereum', status: 'down' },
{ value: 'Solana', status: 'up' },
];
import useGetBannerData from '../../../../hooks/useQuery/useGetBannerData';

function Banner() {
const { data } = useGetBannerData();

const stocks = data || [
{ value: 'Bitcoin', status: 'RISE' },
{ value: 'Ethereum', status: 'STABLE' },
{ value: 'Solana', status: 'DECLINE,' },
];

const getStatusImage = (status: string) => {
switch (status) {
case 'RISE':
return up;
case 'DECLINE':
return down;
case 'STABLE':
return stable;
default:
return stable;
}
};

const getStatusColor = (status: string) => {
switch (status) {
case 'RISE':
return 'text-green';
case 'DECLINE':
return 'text-red';
case 'STABLE':
return 'text-main';
default:
return 'text-main';
}
};

return (
<div className="flex justify-center items-center gap-[5.7rem] pl-[2.9rem] pr-[1.7rem] w-full min-h-[11.8rem] border border-main rounded-4xl bg-white">
<div className="flex flex-col">
<p className="text-[2.6rem] max-[400px]:text-[2.0rem] font-bold text-main">
<p className="text-[2.6rem] max-[415px]:text-[2.4rem] max-[401px]:text-[2.2rem] max-[372px]:text-[2rem] font-bold text-main">
Emotional index
</p>
<div className="flex flex-row gap-[0.8rem]">
Expand All @@ -31,14 +61,14 @@ function Banner() {
className="flex items-center gap-[0.4rem]"
>
<span
className={`text-[1.2rem] max-[400px]:text-[1rem] sm:text-[1.4rem] font-semibold ${stock.status === 'up' ? 'text-green' : 'text-red'}`}
className={`text-[1.2rem] max-[400px]:text-[1rem] sm:text-[1.4rem] font-semibold $${getStatusColor(stock.status)}`}
>
{stock.value}
</span>
<img
src={stock.status === 'up' ? up : down}
src={getStatusImage(stock.status)}
alt={stock.status}
className="w-4 h-4 object-contain"
className="w-5 h-5 object-contain"
/>
</motion.div>
))}
Expand Down
32 changes: 9 additions & 23 deletions src/pages/home/components/Chart/ChartItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,18 @@ import {
import ChartSInfo from './ChartSInfo';
import { useFilterStore } from '../../../../stores/filterStore';
import ChartGradients from './ChartGradients';

interface ChartDataItem {
name: string;
subject1: number;
subject2: number;
subject3: number;
}
import useGetChartData from '../../../../hooks/useQuery/useGetChartData';

type StockType = 'ALL' | 'Bitcoin' | 'Ethereum' | 'Solana';

const data: ChartDataItem[] = [
{ name: '10:00', subject1: 0.5, subject2: 1.0, subject3: 0.8 },
{ name: '11:00', subject1: 0.7, subject2: 0.1, subject3: 0.4 },
{ name: '12:00', subject1: 0.2, subject2: -0.3, subject3: 0.6 },
{ name: '13:00', subject1: 0.5, subject2: 0, subject3: 0.2 },
{ name: '14:00', subject1: -0.1, subject2: -0.7, subject3: 0.9 },
{ name: '15:00', subject1: 0.9, subject2: -0.8, subject3: 1.0 },
{ name: '16:00', subject1: -0.7, subject2: 0.6, subject3: 0.3 },
{ name: '17:00', subject1: 0.9, subject2: 0.4, subject3: -0.3 },
{ name: '18:00', subject1: -0.7, subject2: 1.0, subject3: 0.9 },
];

function ChartItem() {
const currentState = useFilterStore((state) => state.selectedFilter);
const filter = currentState as StockType;

const { data } = useGetChartData({
type: filter,
});

return (
<div className="flex items-center justify-center min-h-[16.8rem] bg-white rounded-xl">
<div className="w-full h-50 relative focus:outline-none">
Expand All @@ -55,7 +41,7 @@ function ChartItem() {
/>

<XAxis
dataKey="name"
dataKey="time"
axisLine={{ stroke: '#e5e7eb' }}
tickLine={false}
tick={{ fill: 'var(--color-black)', fontSize: 8 }}
Expand Down Expand Up @@ -84,7 +70,7 @@ function ChartItem() {
{(filter === 'ALL' || filter === 'Bitcoin') && (
<Area
type="monotone"
dataKey="subject1"
dataKey="Bitcoin"
stroke="var(--color-chart-red)"
strokeWidth={1}
fillOpacity={1}
Expand All @@ -102,7 +88,7 @@ function ChartItem() {
{(filter === 'ALL' || filter === 'Ethereum') && (
<Area
type="monotone"
dataKey="subject2"
dataKey="Ethereum"
stroke="var(--color-chart-purple)"
strokeWidth={1}
fillOpacity={1}
Expand All @@ -120,7 +106,7 @@ function ChartItem() {
{(filter === 'ALL' || filter === 'Solana') && (
<Area
type="monotone"
dataKey="subject3"
dataKey="Solana"
stroke="var(--color-chart-green)"
strokeWidth={1}
fillOpacity={1}
Expand Down
Loading