Skip to content

Commit

Permalink
Merge pull request #542 from gloddy-dev/feature/521-set-country
Browse files Browse the repository at this point in the history
Feature : 국가 설정 구현
  • Loading branch information
guesung authored Jan 3, 2024
2 parents dcf49ef + a66fcfa commit b6680a5
Show file tree
Hide file tree
Showing 42 changed files with 1,165 additions and 142 deletions.
18 changes: 0 additions & 18 deletions .github/workflows/auto-issue-labeler.yml

This file was deleted.

41 changes: 9 additions & 32 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Binary file not shown.
Binary file not shown.
5 changes: 4 additions & 1 deletion next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import withPlaiceholder from '@plaiceholder/next';

import { withSentryConfig } from '@sentry/nextjs';

/**
Expand All @@ -12,6 +11,10 @@ const nextConfig = {
protocol: 'https',
hostname: 'gloddy.s3.ap-northeast-2.amazonaws.com',
},
{
protocol: 'https',
hostname: 'opendata.mofa.go.kr',
},
],
},
experimental: {
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
"react": "18.2.0",
"react-datepicker": "^4.15.0",
"react-dom": "18.2.0",
"react-error-boundary": "^4.0.10",
"react-hook-form": "^7.45.0",
"react-i18next": "^13.2.2",
"react-intersection-observer": "^9.5.2",
Expand Down
2 changes: 2 additions & 0 deletions src/apis/auth/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ export interface SignUpRequest {
birth: string;
gender: GenderType;
personalities: string[];
countryName: string;
countryImage: string;
}

export interface SignUpResponse {
Expand Down
12 changes: 9 additions & 3 deletions src/apis/profile/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ import { useSuspenseQuery } from '@suspensive/react-query';
export const useGetProfile = () =>
useSuspenseQuery(Keys.getProfile(), getProfile, {
select: (data) => {
const { introduce } = data;
const defaultIntroduce = introduce ?? '';
return { ...data, introduce: defaultIntroduce };
const { introduce, countryName, countryImage } = data;
return {
...data,
introduce: introduce || '',
countryName: countryName || 'Korea',
countryImage:
countryImage ||
'https://opendata.mofa.go.kr:8444/fileDownload/images/country_images/flags/241/20220224_233513043.gif',
};
},
});

Expand Down
6 changes: 5 additions & 1 deletion src/apis/profile/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,19 @@ export interface ProfileResponse {
participatedGroupCount: 0;
praiseCount: number;
reviewCount: number;
countryName: string;
countryImage: string;
}

export interface ProfileRequest {
imageUrl: string;
name: string;
birth: string;
gender: 'MAIL' | 'FEMAIL';
introduce: string;
personalities: Array<PersonalityType['keywordDTO']>;
countryName: string;
countryImage: string;
birth: string;
}

export interface PraisesResponse {
Expand Down
94 changes: 94 additions & 0 deletions src/app/[lng]/(main)/community/write/components/ImageSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import Image from 'next/image';
import { memo, useCallback } from 'react';
import { Control, useController } from 'react-hook-form';

import { WriteFormType } from '../type';
import { Icon } from '@/components/Icon';
import { Flex } from '@/components/Layout';
import { Loading } from '@/components/Loading';
import { useFileUpload } from '@/hooks/useFileUpload';

interface ImageSectionProps {
control: Control<WriteFormType>;
}

export default function ImageSection({ control }: ImageSectionProps) {
const {
field: { value, onChange },
} = useController({
name: 'images',
control,
});

const { handleFileUploadClick, isLoading } = useFileUpload((files) => {
onChange([...value, ...files]);
});

const handleDeleteClick = useCallback(
(imageUrl: string) => onChange(value.filter((v) => v !== imageUrl)),
[onChange, value]
);

return (
<section className="px-20 pb-8 pt-16">
<Flex className="gap-8">
{value.map((imageUrl, index) => (
<ImageThumbnail key={imageUrl + index} imageUrl={imageUrl} onClick={handleDeleteClick} />
))}
{isLoading && (
<Flex
direction="column"
justify="center"
align="center"
className="h-96 w-96 rounded-8 bg-card-ui"
>
<Loading />
</Flex>
)}
{value.length < 3 && !(isLoading && value.length === 2) && (
<AddImageButton imageCount={value.length} onClick={handleFileUploadClick} />
)}
</Flex>
</section>
);
}

interface AddImageSectionProps {
imageCount: number;
onClick: () => void;
}

function AddImageButton({ imageCount, onClick }: AddImageSectionProps) {
return (
<Flex
direction="column"
justify="center"
align="center"
className="h-96 w-96 cursor-pointer rounded-8 bg-sub"
onClick={onClick}
>
<Icon id="48-add_photo" width={48} height={48} />
<p className="text-caption text-sign-caption">{imageCount}/3</p>
</Flex>
);
}

interface ImageThumbnailProps {
imageUrl: string;
onClick: (imageUrl: string) => void;
}

const ImageThumbnail = memo(({ imageUrl, onClick }: ImageThumbnailProps) => {
return (
<div className="relative h-96 w-96">
<Image src={imageUrl} alt="select-img" className="rounded-8 object-cover" fill />
<Icon
id="32-close"
width={32}
height={32}
className="absolute right-0 top-0 cursor-pointer"
onClick={() => onClick(imageUrl)}
/>
</div>
);
});
93 changes: 93 additions & 0 deletions src/app/[lng]/(main)/community/write/components/InputSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
'use client';
import { SubmitHandler, useForm } from 'react-hook-form';

import WriteModal from '../components/WriteModal';
import { WriteFormType } from '../type';
import { useTranslation } from '@/app/i18n/client';
import { Button, ButtonGroup } from '@/components/Button';
import MultiImageUploader from '@/components/Image/MultiImageUploader';
import ListBoxController from '@/components/ListBox/ListBoxController';
import { Spacing } from '@/components/Spacing';
import { TextFieldController } from '@/components/TextField';
import { useModal } from '@/hooks/useModal';

export default function InputSection() {
const { open, exit } = useModal();
const { t } = useTranslation('community');
const hookForm = useForm<WriteFormType>({
mode: 'onChange',
defaultValues: {
category: 'NONE',
title: '',
content: '',
images: [],
},
});

const { register, handleSubmit, formState, control } = hookForm;

const onSubmit: SubmitHandler<WriteFormType> = (formData) => {
console.log(formData);
};

const options = [t('create.category.kpop'), t('create.category.qna'), t('create.category.lang')];

return (
<section>
<div className="px-20 pb-8 pt-20">
<Spacing size={4} />
<ListBoxController
name={t('create.category.name')}
options={options}
register={register('category', {
required: true,
validate: (value) => value !== 'NONE',
})}
/>

<Spacing size={4} />
<TextFieldController
placeholder={t('create.title.placeholder')}
hookForm={hookForm}
register={register('title', {
required: true,
maxLength: 60,
})}
maxCount={60}
/>
</div>

<div className="px-20 py-8">
<Spacing size={4} />
<TextFieldController
placeholder={t('create.content.placeholder')}
register={register('content', {
required: true,
maxLength: 300,
})}
hookForm={hookForm}
as="textarea"
maxCount={300}
className={'h-339'}
/>
</div>

<MultiImageUploader<WriteFormType> control={control} name={'images'} />

<Spacing size={60} />
<ButtonGroup>
<Button
onClick={() => {
handleSubmit(onSubmit);
open(() => (
<WriteModal onOkClick={handleSubmit(onSubmit)} onCancelClick={exit} type={'write'} />
));
}}
disabled={!formState.isValid}
>
{t('create.submit.label')}
</Button>
</ButtonGroup>
</section>
);
}
Loading

0 comments on commit b6680a5

Please sign in to comment.