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
5 changes: 5 additions & 0 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ jobs:
- name: 📥 Checkout code
uses: actions/checkout@v2

- name: ⚙️ Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc

- name: ⚙️ Enable Corepack
run: corepack enable

Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/chromatic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Install pnpm
uses: pnpm/action-setup@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 21
node-version-file: .nvmrc

- name: Install pnpm
uses: pnpm/action-setup@v4

- name: Install dependencies
run: pnpm install
- name: Run Chromatic
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/vercel-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ jobs:
- name: 📥 Checkout
uses: actions/checkout@v4

- name: ⚙️ Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc

- name: ⚙️ Enable Corepack & set PNPM
run: |
corepack enable
Expand Down
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20.20.0
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,23 @@ export const partCard = style({
flexDirection: 'column',
alignItems: 'flex-start',
gap: '0.8rem',
width: '100%'
width: '100%',
minWidth: 0
})

export const partRow = style({
width: '100%',
minWidth: 0
})

export const partTag = style({
minWidth: 0,
maxWidth: '100%',
overflow: 'hidden',
textOverflow: 'ellipsis'
})

export const partCount = style({
flexShrink: 0,
whiteSpace: 'nowrap'
})
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,19 @@ export const AnnounceCard = ({ data, onViewDetail }: AnnounceCardProps) => {
<Text variant="xs_caption_medium" color="grayscale60">
파트{idx + 1}
</Text>
<Flex gap="0.8rem" align="center">
<Tag color={tagColor}>{p.positionName}</Tag>
<Text variant="lg_subtitle_bold" color="grayscale90">
<Flex gap="0.8rem" align="center" className={styles.partRow}>
<Tag
color={tagColor}
className={styles.partTag}
title={p.positionName}
>
{p.positionName}
</Tag>
<Text
variant="lg_subtitle_bold"
color="grayscale90"
className={styles.partCount}
>
{p.count}명
</Text>
</Flex>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ export const root = style({
padding: '2rem',
border: `1px solid ${vars.colors.grayscale5}`,
width: '100%',
height: '34.7rem',
height: '100%',
minHeight: 0,
overflow: 'auto'
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const root = style({
padding: '2rem',
border: `1px solid ${vars.colors.grayscale5}`,
width: '100%',
height: '34.7rem',
height: '100%',
overflow: 'auto'
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const root = style({
padding: '2rem',
border: `1px solid ${vars.colors.grayscale5}`,
width: '100%',
height: '34.7rem',
height: '100%',
overflow: 'auto',
display: 'flex',
flexDirection: 'column',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ export const PendingUsers = ({ data, onRemind, isReminding }: PendingUsersProps)
<Profile
size={32}
src={
u.profileImageUrl ||
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTpe8Bx-lLSfBQO6Pi22c5nnBpUaJMeV0hi_s9Vf-CFB-pRlj0ezWnKCtf3b9AvkvxRmLo&usqp=CAU'
u.profileImageUrl
}
alt={u.name}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const AdminHomeDashboardScreen = () => {
return (
<Flex
width="100%"
height="100%"
direction="column"
gap="4rem"
paddingBottom="2.4rem"
Expand All @@ -34,13 +35,25 @@ export const AdminHomeDashboardScreen = () => {
>
<AdminHomeHeader />

<Flex width="100%" direction="column" gap="2rem">
<Flex
width="100%"
direction="column"
gap="2rem"
grow="grow1"
style={{ minHeight: 0 }}
>
<AnnounceCard
data={currentRecruitment}
onViewDetail={() => router.push('/apply-management')}
/>

<Flex width="100%" gap="2rem">
<Flex
width="100%"
gap="2rem"
align="stretch"
grow="grow1"
style={{ minHeight: 0 }}
>
<DocTimeline data={currentRecruitment} />

<Suspense fallback={<OverallProgressSkeleton />}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { ko } from 'date-fns/locale/ko';
import { TIME_STEP } from '@web/utils/application';
import { getClientSideTokens } from '@web/utils/getClientSideTokens';
import { useOrganizationRolesQuery } from '@web/store/query/useOrganizationRolesQuery';
import { useOrganizationRoleGroupsQuery } from '@web/store/query/useOrganizationRoleGroupsQuery';
import { buildRoleGroups, PartOption } from '@web/utils/applicationParts';

export default function PreviewComponent() {
const ctx = useContext<SettingContextType | null>(SettingContext);
Expand All @@ -27,6 +29,9 @@ export default function PreviewComponent() {

const { organizationId } = getClientSideTokens();
const { data: rolesData } = useOrganizationRolesQuery({ organizationId });
const { data: roleGroupsData } = useOrganizationRoleGroupsQuery({
organizationId,
});

const roleNameById = useMemo(() => {
const m = new Map<number, string>();
Expand Down Expand Up @@ -65,48 +70,74 @@ export default function PreviewComponent() {
];

const hasParts = form.applicationParts?.isSelected === true;
const [selectedPartIdx, setSelectedPartIdx] = useState<number>(0);

const roleIds = form.applicationParts?.parts ?? [];

const partNames = useMemo(() => {
return roleIds.map((id) => roleNameById.get(id) ?? `파트(${id})`);
}, [roleIds, roleNameById]);
const partOptions: PartOption[] = useMemo(
() =>
roleIds.map((id) => ({
id,
label: roleNameById.get(id) ?? `파트(${id})`,
})),
[roleIds, roleNameById]
);

const roleGroupOptions = useMemo(() => {
const idSet = new Set(roleIds);
const filteredGroups = (roleGroupsData ?? [])
.map((group) => ({
id: group.id,
name: group.name,
selectionMinCount: group.selectionMinCount,
selectionMaxCount: group.selectionMaxCount,
roles: group.roles
.filter((role) => idSet.has(role.id))
.map((role) => ({ id: role.id, label: role.roleName })),
}))
.filter((group) => group.roles.length > 0);

return buildRoleGroups(partOptions, filteredGroups);
}, [roleGroupsData, roleIds, partOptions]);

const [selectedPartIds, setSelectedPartIds] = useState<number[]>([]);

useEffect(() => {
if (!hasParts) {
setSelectedPartIdx(0);
setSelectedPartIds([]);
return;
}
if (partNames.length > 0 && selectedPartIdx >= partNames.length) {
setSelectedPartIdx(Math.max(0, partNames.length - 1));
}
}, [hasParts, partNames.length, selectedPartIdx]);

setSelectedPartIds((prev) => {
const validIds = new Set(
roleGroupOptions.flatMap((group) => group.roles.map((role) => role.id))
);
let next = prev.filter((id) => validIds.has(id));

roleGroupOptions.forEach((group) => {
const hasSelectionInGroup = group.roles.some((role) =>
next.includes(role.id)
);
if (!hasSelectionInGroup && group.roles.length > 0) {
next = [...next, group.roles[0]!.id];
}
});

return next;
});
}, [hasParts, roleGroupOptions]);

const filteredItems = useMemo(() => {
const items = form.detailItems ?? [];

if (!hasParts || roleIds.length === 0) {
return items.filter((item) => Number(item.responseTarget) === 0);
}

const targetIndex = selectedPartIdx + 1;
const targetRoleId = roleIds[selectedPartIdx];

const out = items.filter((item) => {
return items.filter((item) => {
const target = Number(item.responseTarget);

if (target === 0) return true;

if (target === targetIndex) return true;

if (targetRoleId !== undefined && target === targetRoleId) return true;

return false;
return target === 0 || selectedPartIds.includes(target);
});

return out;
}, [form.detailItems, hasParts, roleIds, selectedPartIdx]);
}, [form.detailItems, hasParts, roleIds.length, selectedPartIds]);

const interval = TIME_STEP[form.interviewDuration];
const allSlots = form.interviewSchedule?.scheduleList ?? [];
Expand All @@ -129,9 +160,7 @@ export default function PreviewComponent() {

<div className={styles.container}>
<Flex direction="column" width="100%" gap="5rem">
<div className={styles.title}>
{form.title || '[한국대학생IT경영학회] 큐시즘 33기 학회원 모집'}
</div>
<div className={styles.title}>{form.title || '공고명'}</div>
<div className={styles.headerWrapper}>
{applicationSchedule.map((s, i) => (
<div key={i} className={styles.item}>
Expand Down Expand Up @@ -160,11 +189,11 @@ export default function PreviewComponent() {
/>
</Flex>

{form.applicationParts?.isSelected && partNames.length > 0 && (
{form.applicationParts?.isSelected && roleGroupOptions.length > 0 && (
<ApplicationPartsPreview
parts={partNames}
selectedIndex={selectedPartIdx}
onChange={setSelectedPartIdx}
roleGroups={roleGroupOptions}
selectedPartIds={selectedPartIds}
onMultiChange={setSelectedPartIds}
/>
)}

Expand Down
Loading
Loading