Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
082caef
feat: myself 컴포넌트 초기 구현
1jiwoo27 Feb 11, 2026
31a820b
chore: import 문 절대 경로로 변경
1jiwoo27 Feb 11, 2026
e4b8f67
feat: report page 구조 초기 구현
1jiwoo27 Feb 11, 2026
75511e4
feat: 분석 페이지 레이아웃 스타일 반영
1jiwoo27 Feb 11, 2026
dcc3e2d
refactor: ReportLegend 컴포넌트 분리
1jiwoo27 Feb 11, 2026
ff81d41
feat: 사용량 안내 subtext 추가
1jiwoo27 Feb 11, 2026
df1dd2d
feat: ReportLegend line variant 추가
1jiwoo27 Feb 11, 2026
90dd331
chore: legend border-radius 10px로 변경
1jiwoo27 Feb 11, 2026
331b6ba
feat: line chart svg로 초기 구현
1jiwoo27 Feb 11, 2026
78f4ea8
chore: 그래프에 필요한 data props로 전달
1jiwoo27 Feb 11, 2026
38008d0
refactor: VerticalGrid 다른 그래프에서도 사용할 수 있도록 리팩터링
1jiwoo27 Feb 11, 2026
8d2bcb6
chore: import문 절대경로로 변경
1jiwoo27 Feb 11, 2026
89f7e23
feat: accountbook 데이터 없을 시, mockdata 불러오기
1jiwoo27 Feb 12, 2026
c4034c9
Merge branch 'develop' of https://github.com/softeerbootcamp-7th/Team…
1jiwoo27 Feb 12, 2026
b5aa568
chore: store 불러오는 불필요한 코드 삭제
1jiwoo27 Feb 12, 2026
6b41d4c
feat: buildPath 함수 차트 파일에 추가
1jiwoo27 Feb 12, 2026
5db8653
chore: prettier 스크립트 실행
1jiwoo27 Feb 12, 2026
e60d61d
feat: verticalGrid 추가
1jiwoo27 Feb 12, 2026
10cd834
chore: verticalGrid 컴포넌트에 className props 추가
1jiwoo27 Feb 12, 2026
409a292
chore: 그래프와 그리드에 relative 속성 추가
1jiwoo27 Feb 12, 2026
64ff6d3
feat: 그래프와 그리드 크기 조정
1jiwoo27 Feb 12, 2026
ac7c971
refactor: VerticalGrid에 positions props 추가하여 일정하지 않은 라벨에서도 사용 가능하도록 변경
1jiwoo27 Feb 12, 2026
bf6cdfa
chore: label 깨지지 않도록 whitespace-nowrap 속성 추가
1jiwoo27 Feb 12, 2026
824ff97
refactor: props 정리 및 불필요한 계산 로직 삭제
1jiwoo27 Feb 12, 2026
12cf18f
feat: mockdata 구조 변경 및 데이터 적용
1jiwoo27 Feb 12, 2026
e9b9d19
feat: 애니메이션 스타일 css 파일로 분리
1jiwoo27 Feb 12, 2026
ee696bf
feat: prevPath fill 속성 추가 (커스텀 스타일 적용)
1jiwoo27 Feb 12, 2026
a32b9ca
chore: 그래프 height 변경
1jiwoo27 Feb 12, 2026
8c8a147
feat: 필요한 count props 추가
1jiwoo27 Feb 12, 2026
09e3d48
chore: animation 변수명 변경
1jiwoo27 Feb 12, 2026
ca39e9c
chore: 라벨 mockData 정보로 변경
1jiwoo27 Feb 12, 2026
e70ad3a
Merge branch 'develop' of https://github.com/softeerbootcamp-7th/Team…
1jiwoo27 Feb 12, 2026
15477cf
refactor: buildPath 파일 분리
1jiwoo27 Feb 12, 2026
85670da
chore: prev 대신 last로 통일
1jiwoo27 Feb 12, 2026
215475e
chore: props 관련 주석 추가
1jiwoo27 Feb 12, 2026
da36349
chore: Legend_Color key 값 변경
1jiwoo27 Feb 12, 2026
070a690
chore: 필요없는 변수 삭제
1jiwoo27 Feb 12, 2026
2033a4e
refactor: buildPath 함수 내 반복되는 로직 분리
1jiwoo27 Feb 12, 2026
a73063b
chore: 컴포넌트명 변경
1jiwoo27 Feb 12, 2026
7f73bae
chore: 바뀐 컴포넌트명에 따라 import 문 수정
1jiwoo27 Feb 12, 2026
0f96f3d
style: pl 추가로 가운데 정렬
1jiwoo27 Feb 12, 2026
9086b7b
chore: 필요한 currencyCode만 불러오도록 조건문 작성
1jiwoo27 Feb 12, 2026
c884faa
Merge branch 'develop' of https://github.com/softeerbootcamp-7th/WEB-…
1jiwoo27 Feb 14, 2026
fffb25d
refactor: 반복되는 ChartItem 타입 분리 및 props에 적용
1jiwoo27 Feb 14, 2026
56e3486
fix: 자동 저장 시 줄바꿈되면서 변경사항으로 인식되는 문제로, .gitattributes에 routeTree 파일 추가
1jiwoo27 Feb 14, 2026
5938d74
refactor: 라벨도 gridPositions 기준으로 순회하도록 변경 (라벨이 없으면 렌더링하지 않게 처리)
1jiwoo27 Feb 14, 2026
f310b78
chore: 함수 호출 부분 상수화
1jiwoo27 Feb 14, 2026
f844887
chore: props 타입 keyof typeof로 통일
1jiwoo27 Feb 15, 2026
aa5fd36
feat: mockdata 구조 변경
1jiwoo27 Feb 15, 2026
1e9d060
refactor: month 단위로 props 구조 재정리
1jiwoo27 Feb 15, 2026
bc6537f
chore: 불필요한 주석 삭제
1jiwoo27 Feb 15, 2026
038896c
chore: className props에서 제거
1jiwoo27 Feb 15, 2026
eb30dcc
chore: 타입 단언 제거 및 countryCode null 가드 추가
1jiwoo27 Feb 15, 2026
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
2 changes: 2 additions & 0 deletions frontend/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 자동 생성되는 라우트 트리 파일의 줄바꿈을 LF로 고정
src/routeTree.gen.ts text eol=lf
30 changes: 30 additions & 0 deletions frontend/src/components/report-page/ReportLegend.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import clsx from 'clsx';

const LEGEND_COLOR = {
primary: 'bg-primary-normal',
secondary: 'bg-cool-neutral-90',
} as const;

const SHAPE_STYLE = {
box: 'size-2.5',
line: 'w-6.25 h-1 rounded-modal-10',
} as const;

interface ReportLegendProps {
color: keyof typeof LEGEND_COLOR;
label: string;
variant?: keyof typeof SHAPE_STYLE;
}

const ReportLegend = ({ color, label, variant = 'box' }: ReportLegendProps) => {
return (
<div className="flex items-center gap-1.5">
<div className={clsx(SHAPE_STYLE[variant], LEGEND_COLOR[color])} />
<span className="label1-normal-regular text-label-alternative">
{label}
</span>
</div>
);
};

export default ReportLegend;
67 changes: 67 additions & 0 deletions frontend/src/components/report-page/VerticalGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import type { ComponentPropsWithoutRef } from 'react';
import { clsx } from 'clsx';

interface VerticalGridProps extends ComponentPropsWithoutRef<'div'> {
steps?: number;
labels: (number | string)[];
positions?: number[]; // 커스텀 위치 배열
}

const VerticalGrid = ({
steps,
labels,
positions,
className,
}: VerticalGridProps) => {
const gridPositions =
positions ||
(steps !== undefined
? Array.from({ length: steps + 1 }, (_, i) => (i / steps) * 100)
: []);

if (gridPositions.length === 0) return null;

return (
<div
className={clsx(
'pointer-events-none absolute inset-0 flex h-full flex-col gap-4 pr-5',
className,
)}
>
<div className="relative flex-1">
{gridPositions.map((position, i) => (
<div
key={i}
className="border-line-normal-normal absolute top-0 h-full border-l border-dashed"
style={{
left: `${position}%`,
}}
/>
))}
</div>
<div className="relative">
{gridPositions.map((position, i) => {
const label = labels[i];
if (label === undefined || label === null) return null;

return (
<div
key={i}
className="text-label-assistive absolute text-xs whitespace-nowrap"
style={{
left: `${position}%`,
transform: 'translateX(-50%)',
}}
>
{typeof label === 'number'
? Math.round(label).toLocaleString()
: label}
</div>
);
})}
</div>
</div>
);
};

export default VerticalGrid;
9 changes: 6 additions & 3 deletions frontend/src/components/report-page/category/ReportBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import CurrencyAmountDisplay from '@/components/currency/CurrencyAmountDisplay';
import CurrencyBadge from '@/components/currency/CurrencyBadge';
import { useReportContext } from '@/components/report-page/ReportContext';

import { type CountryCode } from '@/data/countryCode';
import { useAccountBookStore } from '@/stores/useAccountBookStore';

interface ReportBarProps {
Expand All @@ -30,8 +29,10 @@ const VARIANT_STYLES = {

const ReportBar = ({ value, variant, maxValue }: ReportBarProps) => {
const { currencyType } = useReportContext();
const countryCode = useAccountBookStore((state) => state.accountBook?.localCountryCode) as CountryCode;

const countryCode = useAccountBookStore(
(state) => state.accountBook?.localCountryCode,
);

const styles = VARIANT_STYLES[variant];
const percentage = (value / maxValue) * 100;
const [showAmount, setShowAmount] = useState(false);
Expand All @@ -46,6 +47,8 @@ const ReportBar = ({ value, variant, maxValue }: ReportBarProps) => {
return () => clearTimeout(timer);
}, []);

if (!countryCode) return null;

return (
<div className="flex flex-1 items-center gap-2">
<div
Expand Down
30 changes: 4 additions & 26 deletions frontend/src/components/report-page/category/ReportBarGraph.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,9 @@
import { useMemo } from 'react';
import clsx from 'clsx';

import ReportBarList from '@/components/report-page/category/ReportBarList';
import ReportLegend from '@/components/report-page/ReportLegend';

import type { CategoryId } from '@/types/category';

const LEGEND_COLOR = {
me: 'bg-primary-normal',
other: 'bg-cool-neutral-95',
} as const;

interface ReportBarLegendProps {
color: keyof typeof LEGEND_COLOR;
label: string;
}

const ReportBarLegend = ({ color, label }: ReportBarLegendProps) => {
return (
<div className="flex items-center gap-1.5">
<div className={clsx('h-2.5 w-2.5', LEGEND_COLOR[color])} />
<span className="label1-normal-regular text-label-alternative">
{label}
</span>
</div>
);
};

import { type CategoryId } from '@/types/category';
interface ReportBarGraphProps {
maxLabel: number;
items: {
Expand All @@ -49,8 +27,8 @@ const ReportBarGraph = ({ maxLabel, items }: ReportBarGraphProps) => {
return (
<div className="flex w-145.5 flex-col gap-3.5">
<div className="flex justify-end gap-4">
<ReportBarLegend label="나" color="me" />
<ReportBarLegend label="다른 학생" color="other" />
<ReportLegend label="나" color="primary" />
<ReportLegend label="다른 학생" color="secondary" />
</div>
<ReportBarList items={data} maxLabel={maxLabel} />
</div>
Expand Down
10 changes: 8 additions & 2 deletions frontend/src/components/report-page/category/ReportBarList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ReportBarRow from '@/components/report-page/category/ReportBarRow';
import VerticalGrid from '@/components/report-page/category/VerticalGrid';
import VerticalGrid from '@/components/report-page/VerticalGrid';

import type { CategoryId } from '@/types/category';

Expand All @@ -12,9 +12,15 @@ interface ReportBarListProps {
}[];
}
const ReportBarList = ({ items, maxLabel }: ReportBarListProps) => {
const steps = 6;
const labels = Array.from(
{ length: steps + 1 },
(_, i) => (maxLabel / steps) * i,
);

return (
<div className="relative h-125.25 pt-4.75">
<VerticalGrid steps={6} maxLabel={maxLabel} />
<VerticalGrid steps={steps} labels={labels} className="left-14.75" />
<div className="relative z-10 flex flex-col gap-4.5">
{items.map((item) => (
<ReportBarRow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ const ReportCategory = ({ data }: ReportCategoryProps) => {

return (
<ReportContainer title="월별 지출 비교">
<ReportContent className="h-166.5 w-162.5 gap-7">
<ReportContent className="h-166.5 w-162.5 gap-7 pb-10.25">
<h3 className="heading1-bold text-label-normal">
나랑 같은 국가의 교환학생보다{' '}
<span className="text-primary-normal">{category}</span> 소비가 유독{' '}
<span className="text-primary-strong">{category}</span> 소비가 유독{' '}
{data.isOverSpent ? '많아요' : '적어요'}
</h3>
<ReportBarGraph maxLabel={maxLabelValue} items={data.items} />
Expand Down
47 changes: 0 additions & 47 deletions frontend/src/components/report-page/category/VerticalGrid.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const ReportContent = ({
return (
<div
className={cn(
'rounded-modal-8 bg-cool-neutral-99 flex flex-col justify-between p-8',
'rounded-modal-8 bg-cool-neutral-99 flex flex-col p-8',
className,
)}
>
Expand Down
Loading