Skip to content

Commit

Permalink
Merge branch 'develop' into feat/#973
Browse files Browse the repository at this point in the history
  • Loading branch information
j-nary committed Jan 10, 2025
2 parents ffc6814 + 73f462b commit af2b6fa
Show file tree
Hide file tree
Showing 36 changed files with 123 additions and 48 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy-development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
echo "NEXT_PUBLIC_APP_ENV=development" >> .env
- name: Build
run: yarn build:ci
- name: Move artifacts into dist folder
- name: Move artifacts into dist folder4
run: mkdir group && mv out/* group/ && mv group out
- name: Publish
run: yarn run wrangler pages publish "out" --project-name "${{ secrets.CLOUDFLARE_PAGES_PROJECT_NAME }}" --commit-message "${{ github.sha }}" --branch=main
Expand Down
8 changes: 8 additions & 0 deletions pages/list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const Home: NextPage = () => {
return (
<>
<div>
{/*크루 탭 - 홈, 전체 모임, 내모임, 모임 개설하기 */}
<CrewTab>
<SMobileButtonContainer>
<WriteIcon onClick={handleMakeMeeting} className="make-button" />
Expand All @@ -59,12 +60,18 @@ const Home: NextPage = () => {
<span>모임 개설하기</span>
</SMakeMeetingButton>
</CrewTab>

{/*Notice 슬라이더*/}
<SNoticeWrapper>
<NoticeSlider notices={notices} />
</SNoticeWrapper>

{/*필터 - 필터, 모임 검색, 모임 신청 가이드, 필터 적용 후 생기는 FLEX 박스(chip 모임)*/}
<SFilterWrapper>
<Filter />
</SFilterWrapper>

{/*모임 목록들 - MeetingListOfAll : 내부적으로 쿼리 파라미터 이용하여 필터링 적용*/}
<SSRSafeSuspense
fallback={
<GridLayout mobileType="list">
Expand All @@ -77,6 +84,7 @@ const Home: NextPage = () => {
<MeetingListOfAll />
</SSRSafeSuspense>
</div>

<ConfirmModal
isModalOpened={isModalOpened}
message={`모임을 개설하려면\n프로필 작성이 필요해요`}
Expand Down
17 changes: 11 additions & 6 deletions pages/mine/management/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Option } from '@components/form/Select/OptionItem';
import ItemDescriptionBox from '@components/page/mine/management/ItemDescriptionBox';
import Pagination from '@components/page/list/Pagination';
import { usePageParams, useSortByDateParams, useStatusParams, useTakeParams } from '@hooks/queryString/custom';
import { numberOptionList, sortOptionList } from '@data/options';
import { numberOptionListDefault, numberOptionList, sortOptionList, sortOptionListDefault } from '@data/options';
import { useMutationDownloadMeetingMemberCSV, useQueryGetMeeting } from '@api/API_LEGACY/meeting/hooks';
import Filter from '@components/page/mine/management/Filter';
import DownloadIcon from '@assets/svg/download.svg';
Expand All @@ -31,13 +31,18 @@ const ManagementPage = () => {
});
const isHost = meetingData?.host ?? false;
const { mutate: downloadCSVMutate, isLoading: isDownloadCSVLoading } = useMutationDownloadMeetingMemberCSV();

const convertedNumberTake = numberOptionList[Number(take)] ?? numberOptionListDefault;

const convertedSortTake = sortOptionList[Number(sortByDate)] ?? sortOptionListDefault;

const { isLoading: isManagementDataLoading, data: management } = useQueryGetMeetingPeopleList({
params: {
id,
page: (page || 0) as number,
take: Number(numberOptionList[Number(take) || 0].value),
take: Number(convertedNumberTake.value),
status,
date: sortOptionList[Number(sortByDate) || 0].value as string,
date: sortOptionList[Number(sortByDate) || 0]?.value as string,
},
});

Expand Down Expand Up @@ -82,7 +87,7 @@ const ManagementPage = () => {
) : (
<SSelectNumberWrapper>
<Select
value={numberOptionList[Number(take) || 0]}
value={convertedNumberTake}
options={numberOptionList}
onChange={handleChangeSelectOption(setTake, numberOptionList)}
/>
Expand All @@ -96,14 +101,14 @@ const ManagementPage = () => {
<div>
<SSelectNumberWrapper>
<Select
value={numberOptionList[Number(take) || 0]}
value={convertedNumberTake}
options={numberOptionList}
onChange={handleChangeSelectOption(setTake, numberOptionList)}
/>
</SSelectNumberWrapper>
<SSelectWrapper>
<Select
value={sortOptionList[Number(sortByDate) || 0]}
value={convertedSortTake}
options={sortOptionList}
onChange={handleChangeSelectOption(setSort, sortOptionList)}
/>
Expand Down
7 changes: 6 additions & 1 deletion pages/post/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,12 @@ export default function PostPage() {
};

const { setTarget } = useIntersectionObserver({
onIntersect: ([{ isIntersecting }]) => isIntersecting,
onIntersect: entries => {
const entry = entries[0];
if (entry?.isIntersecting) {
return entry?.isIntersecting;
}
},
});

const handleCreateComment = async (req: PostCommentWithMentionRequest) => {
Expand Down
5 changes: 5 additions & 0 deletions public/assets/svg/bolt_md.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/api/API_LEGACY/meeting/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ interface UseMutateBody<T> {
}

export const useQueryMeetingListOfAll = () => {
//쿼리 파라미터값들을 읽어서, 서버에 모임 리스트 받아오는데 사용
const { value: category } = useCategoryParams();
const { value: status } = useStatusParams();
const { value: search } = useSearchParams();
Expand Down
2 changes: 1 addition & 1 deletion src/components/feed/FeedPostViewer/FeedPostViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export default function FeedPostViewer({
</ContentBody>
<Link href={`/detail?id=${post.meeting.id}`} passHref legacyBehavior>
<GroupButton>
<GroupThumbnail src={post.meeting.imageURL[0].url} alt="" />
<GroupThumbnail src={post.meeting.imageURL[0]?.url} alt="" />
<GroupInformation>
<div>
<GroupCategory isStudy={post.meeting.category === CATEGORY_OPTIONS[0]}>
Expand Down
2 changes: 1 addition & 1 deletion src/components/feed/Modal/FeedCreateModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ function FeedCreateModal({ isModalOpened, meetingId, handleModalClose }: CreateM
userId={Number(me?.orgId)}
groupInfo={{
title: detailData?.title || '',
imageUrl: detailData?.imageURL[THUMBNAIL_IMAGE_INDEX].url || '',
imageUrl: detailData?.imageURL[THUMBNAIL_IMAGE_INDEX]?.url || '',
category: detailData?.category || '',
}}
title="피드 작성"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function FeedCreateWithSelectMeetingModal({ isModalOpened, handleModalClose }: C

const { isValid } = formMethods.formState;
const meetingType = formMethods.getValues('meetingId')
? attendMeetingList?.data.filter(item => item.id == formMethods.getValues('meetingId'))[0].category
? attendMeetingList?.data.filter(item => item.id == formMethods.getValues('meetingId'))[0]?.category
: '';

const hostname = typeof window !== 'undefined' ? window.location.hostname : '';
Expand Down
2 changes: 1 addition & 1 deletion src/components/feed/Modal/FeedEditModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function FeedEditModal({ isModalOpened, postId, handleModalClose }: EditModal) {
userId={Number(me?.orgId)}
groupInfo={{
title: postData?.meeting?.title || '',
imageUrl: postData?.meeting?.imageURL[THUMBNAIL_IMAGE_INDEX].url || '',
imageUrl: postData?.meeting?.imageURL[THUMBNAIL_IMAGE_INDEX]?.url || '',
category: postData?.meeting?.category || '',
}}
title="피드 수정"
Expand Down
2 changes: 1 addition & 1 deletion src/components/feed/Modal/FeedFormPresentation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ function FeedFormPresentation({

const uploadFile = async (file: File) => {
const extension = file.type.split('/')[1];
const { url, fields } = await getPresignedUrl(extension);
const { url, fields } = await getPresignedUrl(extension ?? '');
await uploadImage(file, url, fields);
const imageUrls = imageS3Bucket + fields.key;
return imageUrls;
Expand Down
2 changes: 1 addition & 1 deletion src/components/form/Calendar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const CalendarInputForm = ({ selectedDate, setSelectedDate, error }: Props) => {
value={selectedDate ? dayjs(selectedDate, 'YYYY-MM-DD').toDate() : null}
onClickDay={date => setSelectedDate(dayjs(date).format('YYYY.MM.DD'))}
formatDay={(locale, date) => dayjs(date).format('D')}
formatShortWeekday={(locale, date) => ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'][date.getDay()]}
formatShortWeekday={(locale, date) => ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'][date.getDay()] ?? ''}
showNeighboringMonth={false}
next2Label={null}
prev2Label={null}
Expand Down
4 changes: 2 additions & 2 deletions src/components/form/Presentation/JoinablePartsField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Option } from '@components/form/Select/OptionItem';
import { parts } from '@data/options';
import { defaultParts, parts } from '@data/options';
import { Chip } from '@sopt-makers/ui';

interface JoinablePartsFieldProps {
Expand Down Expand Up @@ -33,7 +33,7 @@ const JoinablePartsField = ({ value, onChange }: JoinablePartsFieldProps) => {

// 모든 개별 파트가 선택되었으면 'all' 옵션도 활성화
if (updatedParts.length === parts.length - 1) {
updatedParts.push(parts[0]); // 'all'을 활성화
updatedParts.push(parts[0] ?? defaultParts); // 'all'을 활성화
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/components/form/Presentation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import CheckSelectedIcon from '@assets/svg/checkBox/form_selected.svg';
import CheckUnselectedIcon from '@assets/svg/checkBox/form_unselected.svg';
import { IconAlertCircle } from '@sopt-makers/icons';
import { useDialog } from '@sopt-makers/ui';
import sopt_schedule_tooltip from 'public/assets/images/sopt_schedule_tooltip.png';
import BubblePointIcon from 'public/assets/svg/bubble_point.svg';
import sopt_schedule_tooltip from '@assets/images/sopt_schedule_tooltip.png';
import BubblePointIcon from '@assets/svg/bubble_point.svg';
import JoinablePartsField from '@components/form/Presentation/JoinablePartsField';
import CoLeader from './CoLeader';

Expand Down Expand Up @@ -115,7 +115,7 @@ function Presentation({
return;
}
const [file] = [...e.target.files];
const url = await uploadFile(file);
const url = await uploadFile(file ?? new File([], 'default.txt'));
handleChangeImage(index, url);
};

Expand Down Expand Up @@ -146,7 +146,7 @@ function Presentation({

const uploadFile = async (file: File) => {
const extension = file.type.split('/')[1];
const { url, fields } = await getPresignedUrl(extension);
const { url, fields } = await getPresignedUrl(extension ?? '');
await uploadImage(file, url, fields);
const imageUrls = imageS3Bucket + fields.key;
return imageUrls;
Expand Down
13 changes: 12 additions & 1 deletion src/components/form/SearchMention/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ interface mentionableDataType {
profileImageUrl: string;
}

const defaultMentionableDataType = {
id: 0,
display: '',
orgId: 0,
userId: 0,
userName: '',
recentPart: '',
recentGeneration: 0,
profileImageUrl: '',
};

interface SearchMentionProps {
mentionUserList: mentionableDataType[];
inputRef: React.RefObject<HTMLTextAreaElement>;
Expand Down Expand Up @@ -59,7 +70,7 @@ const SearchMention = ({

if (suggestions.length > 0) {
// select the first suggestion
handleUserClick(suggestions[0]);
handleUserClick(suggestions[0] ?? defaultMentionableDataType);
e.preventDefault();
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/components/form/Select/BaseSelect/BaseSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Listbox } from '@headlessui/react';
import Label from '@components/form/Label';
import Button from '../Button';
import OptionItem, { Option } from '../OptionItem';
import OptionItem, { defaultOption, Option } from '../OptionItem';
import ErrorMessage from '../../ErrorMessage';
import { styled } from 'stitches.config';
import { MultipleSelectProps, SelectProps } from '../types/props';
Expand All @@ -18,7 +18,7 @@ export default function BaseSelect(props: SelectProps | MultipleSelectProps) {
// NOTE: 전체 옵션을 선택한 경우, 전체 옵션을 체크해주어야 한다.
if (isAllSelect(lastSelectedItem)) return onChange(options);
// NOTE: 전체 옵션을 선택 해제한 경우, 전체 옵션을 체크 해제해주어야 한다.
if (isAllUnselected(value, newValues)) return onChange([value[0]]);
if (isAllUnselected(value, newValues)) return onChange([value[0] ?? defaultOption]);
// NOTE: 전체 선택되어 있는 상황에서 다른 옵션을 체크 해제하는 경우 전체 옵션도 해제해주어야 한다.
if (newValues.length !== options.length) {
newValues = newValues.filter(v => v.value !== 'all');
Expand All @@ -35,12 +35,12 @@ export default function BaseSelect(props: SelectProps | MultipleSelectProps) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const selectedItems = value?.filter(v => v.value).sort((a, b) => a.order! - b.order!);
// NOTE: 선택된 옵션이 존재하지 않거나 빈 배열일경우 디폴트 옵션을 라벨로 표기한다.
if (!selectedItems?.length) return { text: value?.[0].label, active: false };
if (!selectedItems?.length) return { text: value?.[0]?.label, active: false };
// NOTE: 전체 선택이 포함된경우 '전체' 라고 표기한다.
if (isAllSelect(selectedItems[0])) return { text: '전체', active: true };
// NOTE: 전체 선택이 포함되지 않은 경우 선택된 옵션을 표기한다. 이때 개수가 여러개면 '00 외 0' 형식으로 보여준다.
const suffix = selectedItems.length > 1 ? ` 외 ${selectedItems.length - 1}` : '';
return { text: `${selectedItems[0].label}${suffix}`, active: true };
return { text: `${selectedItems[0]?.label}${suffix}`, active: true };
}
return { text: value?.label, active: Boolean(value?.value) };
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Listbox } from '@headlessui/react';
import useModal from '@hooks/useModal';
import MobileOptionItem from '../OptionItem/MobileOptionItem';
import BottomSheetDialog from './BottomSheetDialog';
import { Option } from '../OptionItem';
import { defaultOption, Option } from '../OptionItem';
import { MultipleSelectProps, SelectProps } from '../types/props';
import { isAllSelect, isAllUnselected } from '../utils';

Expand All @@ -25,7 +25,7 @@ export default function BottomSheetSelect({
// NOTE: 전체 옵션을 선택한 경우, 전체 옵션을 체크해주어야 한다.
if (isAllSelect(lastSelectedItem)) return onChange(options);
// NOTE: 전체 옵션을 선택 해제한 경우, 전체 옵션을 체크 해제해주어야 한다.
if (isAllUnselected(value, newValues)) return onChange([value[0]]);
if (isAllUnselected(value, newValues)) return onChange([value[0] ?? defaultOption]);
// NOTE: 전체 선택되어 있는 상황에서 다른 옵션을 체크 해제하는 경우 전체 옵션도 해제해주어야 한다.
if (newValues.length !== options.length) {
newValues = newValues.filter(v => v.value !== 'all');
Expand All @@ -42,12 +42,12 @@ export default function BottomSheetSelect({
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const selectedItems = value?.filter(v => v.value).sort((a, b) => a.order! - b.order!);
// NOTE: 선택된 옵션이 존재하지 않거나 빈 배열일경우 디폴트 옵션을 라벨로 표기한다.
if (!selectedItems?.length) return { text: value?.[0].label, active: false };
if (!selectedItems?.length) return { text: value?.[0]?.label, active: false };
// NOTE: 전체 선택이 포함된경우 '전체' 라고 표기한다.
if (isAllSelect(selectedItems[0])) return { text: '전체', active: true };
// NOTE: 전체 선택이 포함되지 않은 경우 선택된 옵션을 표기한다. 이때 개수가 여러개면 '00 외 0' 형식으로 보여준다.
const suffix = selectedItems.length > 1 ? ` 외 ${selectedItems.length - 1}` : '';
return { text: `${selectedItems[0].label}${suffix}`, active: true };
return { text: `${selectedItems[0]?.label}${suffix}`, active: true };
}
return { text: value?.label, active: Boolean(value?.value) };
};
Expand Down
5 changes: 5 additions & 0 deletions src/components/form/Select/OptionItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ export interface Option {
order?: number;
}

export const defaultOption = {
label: '',
value: '',
} as const;

interface OptionItemProps {
css?: CSSType;
option: Option;
Expand Down
2 changes: 1 addition & 1 deletion src/components/groupBrowsing/mobileSizeCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const MobileSizeCard: FC<GroupBrowsingCardItem> = ({ id, title, category, mStart
<SStatus recruitingStatus={newStatus}>{ACTION_STATUS[newStatus]}</SStatus>
<SThumbnailImage
css={{
backgroundImage: `url(${imageURL[0].url && getResizedImage(imageURL[0].url, 140)})`,
backgroundImage: `url(${getResizedImage(imageURL[0]?.url ?? '', 140)})`,
backgroundSize: 'cover',
}}
/>
Expand Down
15 changes: 13 additions & 2 deletions src/components/modal/FloatingButtonModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useRouter } from 'next/router';
import { keyframes, styled } from 'stitches.config';
import FeedIcon from '../../../public/assets/svg/floating_button_feed_icon.svg';
import GroupIcon from '../../../public/assets/svg/floating_button_group_icon.svg';
import BoltIcon from '@assets/svg/bolt_md.svg';
import NoJoinedGroupModal from './NoJoinedGroupModal';

const FloatingButtonModal = (props: { isActive: boolean; handleOptionClose: () => void }) => {
Expand Down Expand Up @@ -35,6 +36,12 @@ const FloatingButtonModal = (props: { isActive: boolean; handleOptionClose: () =
router.push('/make');
};

const handleBoltCreateButtonClick = () => {
//todo: 번쩍 개설을 위한 정보를 넘겨주면서 라우팅하기
ampli.clickMakeGroup({ location: router.pathname });
router.push('/make');
};

const handleFeedCreateButtonClick = () => {
if (me?.orgId) {
ampli.clickFeedPosting({ user_id: Number(me?.orgId), location: router.pathname });
Expand All @@ -44,6 +51,10 @@ const FloatingButtonModal = (props: { isActive: boolean; handleOptionClose: () =

return (
<Container isActive={isActive}>
<Button onClick={handleBoltCreateButtonClick}>
<BoltIcon style={{ marginRight: '4px' }} />
번쩍 개설
</Button>
<Button onClick={handleGroupCreateButtonClick}>
<GroupIcon style={{ marginRight: '4px' }} />
모임 개설
Expand All @@ -70,7 +81,7 @@ const fadeOut = keyframes({

const Container = styled('div', {
width: '160px',
height: '112px',
height: 'auto',
zIndex: '$3',
position: 'absolute',
bottom: '76px',
Expand All @@ -96,7 +107,7 @@ const Container = styled('div', {
},
'@tablet': {
width: '140px',
height: '90px',
height: 'auto',
borderRadius: '18px',
bottom: '72px',
padding: '$6 $0 $6 $4',
Expand Down
Loading

0 comments on commit af2b6fa

Please sign in to comment.