-
- onNameChange(e.target.value)}
- className="bg-container-neutral-alternative rounded-sm border-transparent px-400 py-300"
- />
+
-
- onDescriptionChange(e.target.value)}
- maxLength={30}
- placeholder="동아리를 소개하는 짧은 글을 작성해주세요"
- className="bg-container-neutral-alternative rounded-sm border-transparent px-400 py-300"
- />
+
+
diff --git a/src/components/admin/club-info/ClubInfoContactSection.tsx b/src/components/admin/club-info/ClubInfoContactSection.tsx
index 55689566..ccd4277e 100644
--- a/src/components/admin/club-info/ClubInfoContactSection.tsx
+++ b/src/components/admin/club-info/ClubInfoContactSection.tsx
@@ -32,7 +32,7 @@ function ClubInfoContactSection({
title="연락처"
titleGapClassName="mt-[58px]"
contentClassName="gap-0"
- className="pb-[70px]"
+ className="pb-[40px]"
>
{title}
-
+
diff --git a/src/components/admin/club-info/ClubInfoBasicSection.tsx b/src/components/admin/club-info/ClubInfoBasicSection.tsx
index b1b02368..b18f0c2c 100644
--- a/src/components/admin/club-info/ClubInfoBasicSection.tsx
+++ b/src/components/admin/club-info/ClubInfoBasicSection.tsx
@@ -40,21 +40,41 @@ function ClubInfoBasicSection({
{title}
+
{children}
+ onNameChange(e.target.value)}
+ maxLength={30}
+ className="bg-container-neutral-alternative rounded-sm border-transparent px-400 py-300"
+ />
+
+
+ {clubName.length}/30
+
+
+
+ onDescriptionChange(e.target.value)}
+ maxLength={30}
+ placeholder="동아리를 소개하는 짧은 글을 작성해주세요"
+ className="bg-container-neutral-alternative rounded-sm border-transparent px-400 py-300"
+ />
+
+ {descriptionError ? (
+ {descriptionError}
+ ) : (
+
+ )}
+
+ {description.length}/30
+
+
+
+
{isEditMode && (
- {label}
+
+ {label}
{children}
{error ? (
{error}
diff --git a/src/components/attendance/AttendanceHistoryContent.tsx b/src/components/attendance/AttendanceHistoryContent.tsx
index cd69256d..e720797f 100644
--- a/src/components/attendance/AttendanceHistoryContent.tsx
+++ b/src/components/attendance/AttendanceHistoryContent.tsx
@@ -81,7 +81,7 @@ function AttendanceHistoryContent({ summary, errorMessage }: AttendanceHistoryCo
-
+
diff --git a/src/components/auth/hub/CreateClubForm.tsx b/src/components/auth/hub/CreateClubForm.tsx
index 33698538..adbb7838 100644
--- a/src/components/auth/hub/CreateClubForm.tsx
+++ b/src/components/auth/hub/CreateClubForm.tsx
@@ -60,6 +60,8 @@ function CreateClubForm({ schoolNames, schoolLoadError = false }: CreateClubForm
const contactType = useWatch({ control, name: 'contactType' });
const email = useWatch({ control, name: 'email' });
+ const clubName = useWatch({ control, name: 'name' });
+ const description = useWatch({ control, name: 'description' });
const hasValidEmail = Boolean(email?.trim()) && !errors.email;
const isEmailContactDisabled = !hasValidEmail;
@@ -143,19 +145,49 @@ function CreateClubForm({ schoolNames, schoolLoadError = false }: CreateClubForm
{/* 동아리 이름 */}
-
-
+
+
+
{/* 동아리 소개 */}
-
+
- 30자 제한
+
{/* 동아리 기수 */}
diff --git a/src/components/ui/Input.tsx b/src/components/ui/Input.tsx
index b5d69866..45988cb1 100644
--- a/src/components/ui/Input.tsx
+++ b/src/components/ui/Input.tsx
@@ -19,10 +19,19 @@ interface InputProps extends InputHTMLAttributes {
clearable?: boolean;
error?: boolean;
wrapperClassName?: string;
+ clearButtonClassName?: string;
ref?: React.Ref;
}
-function Input({ className, clearable, error, wrapperClassName, ref, ...props }: InputProps) {
+function Input({
+ className,
+ clearable,
+ error,
+ wrapperClassName,
+ clearButtonClassName,
+ ref,
+ ...props
+}: InputProps) {
const hasTypo = className?.split(' ').some((c) => c.startsWith('typo-'));
const typoClass = hasTypo ? undefined : 'typo-body2';
const innerRef = useRef(null);
@@ -99,6 +108,7 @@ function Input({ className, clearable, error, wrapperClassName, ref, ...props }:
'flex items-center',
'text-icon-normal',
'cursor-pointer transition-colors',
+ clearButtonClassName,
)}
aria-label="입력 내용 지우기"
>
diff --git a/src/hooks/home/useHomeGuard.ts b/src/hooks/home/useHomeGuard.ts
index e2290307..961f89bd 100644
--- a/src/hooks/home/useHomeGuard.ts
+++ b/src/hooks/home/useHomeGuard.ts
@@ -3,13 +3,12 @@
import { useEffect, useSyncExternalStore } from 'react';
import { useRouter } from 'next/navigation';
import { isAxiosError } from 'axios';
-import { useClubActions, useClubId, useClubName, useClubStore } from '@/stores/useClubStore';
+import { useClubActions, useClubId, useClubStore } from '@/stores/useClubStore';
import { useHomeQuery } from './useHomeQuery';
export function useHomeGuard() {
const router = useRouter();
const clubId = useClubId();
- const clubName = useClubName();
const { reset } = useClubActions();
const { error } = useHomeQuery();
@@ -21,11 +20,11 @@ export function useHomeGuard() {
useEffect(() => {
if (!hydrated) return;
- if (!clubId || !clubName) {
+ if (!clubId) {
reset();
router.replace('/hub');
}
- }, [hydrated, clubId, clubName, reset, router]);
+ }, [hydrated, clubId, reset, router]);
useEffect(() => {
if (isAxiosError(error) && error.response?.status === 404) {
+
+ {errors.name?.message ? (
+
+ {errors.name.message}
+
+ ) : null}
+
+
+ {(clubName ?? '').length}/30
+
+
+
+ {errors.description?.message ? (
+
+ {errors.description.message}
+
+ ) : null}
+
+
+ {(description ?? '').length}/30
+
+