diff --git a/.replit b/.replit
index b0526f5..ae48c28 100644
--- a/.replit
+++ b/.replit
@@ -18,6 +18,10 @@ externalPort = 80
localPort = 34047
externalPort = 3002
+[[ports]]
+localPort = 36455
+externalPort = 3003
+
[[ports]]
localPort = 37531
externalPort = 3001
diff --git a/client/src/components/LoginModal.tsx b/client/src/components/LoginModal.tsx
index bcd31ad..830cfb9 100644
--- a/client/src/components/LoginModal.tsx
+++ b/client/src/components/LoginModal.tsx
@@ -78,6 +78,8 @@ export default function LoginModal({ isOpen, onClose }: LoginModalProps) {
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
+ onInvalid={(e) => (e.target as HTMLInputElement).setCustomValidity('Please enter your username')}
+ onInput={(e) => (e.target as HTMLInputElement).setCustomValidity('')}
placeholder="아이디를 입력하세요"
required
data-testid="input-username"
@@ -90,6 +92,8 @@ export default function LoginModal({ isOpen, onClose }: LoginModalProps) {
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
+ onInvalid={(e) => (e.target as HTMLInputElement).setCustomValidity('Please enter your password')}
+ onInput={(e) => (e.target as HTMLInputElement).setCustomValidity('')}
placeholder="비밀번호를 입력하세요"
required
data-testid="input-password"
diff --git a/client/src/pages/Auctions.tsx b/client/src/pages/Auctions.tsx
index 9f77672..b9e87aa 100644
--- a/client/src/pages/Auctions.tsx
+++ b/client/src/pages/Auctions.tsx
@@ -342,6 +342,8 @@ export default function Auctions() {
min={parseFloat(selectedAuction.currentBid || "0") + 1}
value={bidForm.amount}
onChange={(e) => setBidForm(prev => ({ ...prev, amount: e.target.value }))}
+ onInvalid={(e) => (e.target as HTMLInputElement).setCustomValidity('Please enter a bid amount')}
+ onInput={(e) => (e.target as HTMLInputElement).setCustomValidity('')}
placeholder={`Minimum: $${(parseFloat(selectedAuction.currentBid || "0") + 1).toFixed(2)}`}
required
data-testid="input-bid-amount"
@@ -359,6 +361,8 @@ export default function Auctions() {
max="100"
value={bidForm.qualityScore}
onChange={(e) => setBidForm(prev => ({ ...prev, qualityScore: e.target.value }))}
+ onInvalid={(e) => (e.target as HTMLInputElement).setCustomValidity('Please enter a quality score (1-100)')}
+ onInput={(e) => (e.target as HTMLInputElement).setCustomValidity('')}
placeholder="Your self-assessed quality score"
required
data-testid="input-quality-score"
diff --git a/client/src/pages/Landing.tsx b/client/src/pages/Landing.tsx
index 27dc1aa..db0d46f 100644
--- a/client/src/pages/Landing.tsx
+++ b/client/src/pages/Landing.tsx
@@ -142,6 +142,8 @@ export default function Landing() {
setLoginForm(prev => ({ ...prev, username: e.target.value }))}
+ onInvalid={(e) => (e.target as HTMLInputElement).setCustomValidity('Please enter your username')}
+ onInput={(e) => (e.target as HTMLInputElement).setCustomValidity('')}
placeholder="Enter username"
required
data-testid="input-username"
@@ -154,6 +156,8 @@ export default function Landing() {
type="password"
value={loginForm.password}
onChange={(e) => setLoginForm(prev => ({ ...prev, password: e.target.value }))}
+ onInvalid={(e) => (e.target as HTMLInputElement).setCustomValidity('Please enter your password')}
+ onInput={(e) => (e.target as HTMLInputElement).setCustomValidity('')}
placeholder="Enter password"
required
data-testid="input-password"
@@ -198,6 +202,8 @@ export default function Landing() {
setRequestForm(prev => ({ ...prev, name: e.target.value }))}
+ onInvalid={(e) => (e.target as HTMLInputElement).setCustomValidity('Please enter outlet name')}
+ onInput={(e) => (e.target as HTMLInputElement).setCustomValidity('')}
placeholder="Enter outlet name"
required
data-testid="input-outlet-name"