diff --git a/src/features/post/ui/ImageUploadGrid.tsx b/src/features/post/ui/ImageUploadGrid.tsx
index 8ddbe2a..1fd0348 100644
--- a/src/features/post/ui/ImageUploadGrid.tsx
+++ b/src/features/post/ui/ImageUploadGrid.tsx
@@ -2,7 +2,7 @@
import { useRef, useEffect } from 'react';
import Image from 'next/image';
-import { IconPlus, IconX } from '@tabler/icons-react';
+import { IconX } from '@tabler/icons-react';
interface ImageUploadGridProps {
previews: string[];
@@ -70,10 +70,9 @@ export function ImageUploadGrid({
)}
@@ -85,7 +84,7 @@ export function ImageUploadGrid({
}).map((_, i) => (
))}
diff --git a/src/features/post/ui/ImageUploadSlot.tsx b/src/features/post/ui/ImageUploadSlot.tsx
index 235a5e2..4cda69f 100644
--- a/src/features/post/ui/ImageUploadSlot.tsx
+++ b/src/features/post/ui/ImageUploadSlot.tsx
@@ -2,7 +2,7 @@
import { useRef, useEffect } from 'react';
import Image from 'next/image';
-import { IconPlus, IconX } from '@tabler/icons-react';
+import { IconX } from '@tabler/icons-react';
interface ImageUploadSlotProps {
preview: string | null;
@@ -49,7 +49,7 @@ export function ImageUploadSlot({
return (
{preview ? (
inputRef.current?.click()}
- className="flex h-full w-full flex-col items-center justify-center gap-1 text-gray-300"
+ className="flex h-full w-full items-center justify-center rounded-xl border border-gray-200 bg-white text-xs font-semibold text-gray-400 transition-colors hover:border-gray-300 hover:bg-gray-50"
>
-
- 사진 추가
+ 사진 추가
)}
diff --git a/src/features/post/ui/ReceiptCard.tsx b/src/features/post/ui/ReceiptCard.tsx
index a012bb9..f05002b 100644
--- a/src/features/post/ui/ReceiptCard.tsx
+++ b/src/features/post/ui/ReceiptCard.tsx
@@ -1,13 +1,12 @@
-import { Input } from '@frontend/design-system';
import {
buildOfferGoalAmount,
- buildOfferParticipationRows,
buildRequestGoalAmount,
- buildRequestParticipationRows,
formatKrw,
+ parseBudgetAmount,
parsePartnerCount,
} from '../model/pricing-preview';
import { FormCard } from './FormCard';
+import { PostTextInput } from './FormControls';
import { FormField } from './FormField';
type BaseReceiptCardProps = {
@@ -89,20 +88,19 @@ export function ReceiptCard(props: ReceiptCardProps) {
props.priceCapPerPerson,
)
: null;
- const offerRows =
- props.type === 'OFFER'
- ? buildOfferParticipationRows(
- props.desiredPrice,
- props.maxPartnerCount,
- )
- : [];
- const requestRows =
+ const offerPerPersonPreview =
+ props.type === 'OFFER' &&
+ offerGoalAmount !== null &&
+ maxPartnerCount !== null
+ ? {
+ amount: Math.floor(offerGoalAmount / maxPartnerCount),
+ remainder: offerGoalAmount % maxPartnerCount,
+ }
+ : null;
+ const requestPerPersonPreview =
props.type === 'REQUEST'
- ? buildRequestParticipationRows(
- props.maxPartnerCount,
- props.priceCapPerPerson,
- )
- : [];
+ ? parseBudgetAmount(props.priceCapPerPerson)
+ : null;
return (
@@ -133,8 +131,12 @@ export function ReceiptCard(props: ReceiptCardProps) {
@@ -271,51 +289,36 @@ export function ReceiptCard(props: ReceiptCardProps) {
- {props.type === 'OFFER'
- ? '참여 인원별 1인당 금액'
- : '참여 인원별 예산 흐름'}
+ 1인당 예상 금액
- {props.type === 'OFFER'
- ? '입력과 동시에 계산'
- : '상한 금액 기준 자동 계산'}
+ 누적 목록 없이 요약
{props.type === 'OFFER' ? (
- offerRows.length > 0 ? (
-
- {offerRows.map((row) => (
-
0 ? '약 ' : ''}${formatKrw(row.perPersonAmount)} / 1인`}
- description={
- row.participantCount === 1
- ? '혼자 진행하면 전체 희망 예산을 그대로 부담해요.'
- : row.remainder > 0
- ? `${row.participantCount}명이 함께하면 1원 단위 차이는 마지막 정산에서 조정될 수 있어요.`
- : `${row.participantCount}명이 함께하면 1인당 금액이 동일하게 나뉘어요.`
- }
- />
- ))}
-
+ offerPerPersonPreview ? (
+
0 ? '약 ' : ''}${formatKrw(offerPerPersonPreview.amount)} / 1인`}
+ description={
+ offerPerPersonPreview.remainder > 0
+ ? '1원 단위 차이는 마지막 정산에서 조정될 수 있어요.'
+ : '최대 파트너 수로 나눴을 때의 1인당 예상 금액이에요.'
+ }
+ />
) : (
-
+
)
- ) : requestRows.length > 0 ? (
-
- {requestRows.map((row) => (
-
- ))}
-
+ ) : requestPerPersonPreview !== null &&
+ maxPartnerCount !== null ? (
+
) : (
-
+
)}
diff --git a/src/features/post/ui/post-form/OfferDetailsSection.tsx b/src/features/post/ui/post-form/OfferDetailsSection.tsx
index 47086df..267db02 100644
--- a/src/features/post/ui/post-form/OfferDetailsSection.tsx
+++ b/src/features/post/ui/post-form/OfferDetailsSection.tsx
@@ -1,5 +1,5 @@
-import { Textarea } from '@frontend/design-system';
import { FormCard } from '../FormCard';
+import { PostTextarea } from '../FormControls';
import { FormField } from '../FormField';
import { ImageUploadSlot } from '../ImageUploadSlot';
@@ -25,10 +25,9 @@ export function OfferDetailsSection({
onAutoCloseChange,
}: OfferDetailsSectionProps) {
return (
-
-
-
);
}
diff --git a/src/features/post/ui/post-form/PriceInputSection.tsx b/src/features/post/ui/post-form/PriceInputSection.tsx
index 067056a..ffe7959 100644
--- a/src/features/post/ui/post-form/PriceInputSection.tsx
+++ b/src/features/post/ui/post-form/PriceInputSection.tsx
@@ -8,12 +8,12 @@ import type {
IncludedItem,
PriceBreakdown,
} from '@/entities/spot/simulation-types';
-
-type PriceInputSectionProps = {
- value?: PriceBreakdown;
- onChange: (next: PriceBreakdown | undefined) => void;
- optional?: boolean;
-};
+import {
+ PostAddButton,
+ PostRemoveButton,
+ PostTextInput,
+ PostTextarea,
+} from '../FormControls';
const MECHANISMS: { value: AddOnMechanism; label: string }[] = [
{ value: 'fixed', label: '정액 추가' },
@@ -21,6 +21,12 @@ const MECHANISMS: { value: AddOnMechanism; label: string }[] = [
{ value: 'realcost', label: '실비 분담' },
];
+type PriceInputSectionProps = {
+ value?: PriceBreakdown;
+ onChange: (next: PriceBreakdown | undefined) => void;
+ optional?: boolean;
+};
+
function ensurePrice(value: PriceBreakdown | undefined): PriceBreakdown {
return (
value ?? {
@@ -86,7 +92,7 @@ export function PriceInputSection({
});
return (
-