Skip to content

Commit

Permalink
feat: add SharedProfilePage
Browse files Browse the repository at this point in the history
  • Loading branch information
ooooorobo committed Sep 18, 2024
1 parent bc79529 commit 9a75843
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 5 deletions.
40 changes: 40 additions & 0 deletions src/app/routes/share.$key.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { LoaderFunction } from '@remix-run/node';
import { authenticate } from '../server/authenticate';
import { getInfoBySharingId } from '../../types';
import { useLoaderData } from '@remix-run/react';
import { useMemo } from 'react';
import { convertDtoToProfile } from '../../entities/profile/model/convertProfileToDto';
import { MyProfileProvider } from '../../entities/profile/model/myProfileStore';
import { ProfilePage } from '../../pages/profile/ProfilePage';

export const loader: LoaderFunction = async ({ request, params }) => {
const accessToken = await authenticate(request);

const { key } = params;

if (!key) {
throw new Response('', {
status: 404,
statusText: 'Not Found',
});
}

const { data } = await getInfoBySharingId(key, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});

return { profile: data };
};

export default function Page() {
const { profile } = useLoaderData<typeof loader>();
const profileInitialState = useMemo(() => convertDtoToProfile(profile.userInfo), [profile.userInfo]);

return (
<MyProfileProvider initialState={profileInitialState}>
<ProfilePage />
</MyProfileProvider>
);
}
7 changes: 2 additions & 5 deletions src/pages/profile/ProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useIdealPartnerStore } from 'src/entities/ideal_partner/model/idealPart
import { Link } from '@remix-run/react';
import { Header } from 'src/shared/ui/layout/Header/Header';
import { Theme } from 'src/shared/styles/constants';
import { ImageLayout } from '../../shared/ui/ImageLayout/ImageLayout';

export const ProfilePage = () => {
const { ref, inView } = useInView();
Expand Down Expand Up @@ -57,11 +58,7 @@ export const ProfilePage = () => {
)}
</Header>
<ScrollView rootClassName={styles.Body}>
<div className={styles.ImageLayout} data-itemcount={Math.min(urls.length, 5)}>
{urls.map((url) => (
<img key={url} src={url} alt={'프로필 이미지'} />
))}
</div>
<ImageLayout urls={urls} />
<h1 className={styles.Name} ref={ref}>
{profile.name}({profile.gender}, {age})
</h1>
Expand Down
40 changes: 40 additions & 0 deletions src/pages/shared_profile/SharedProfilePage.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.Wrapper {
display: flex;
flex-direction: column;
overflow: hidden;
height: 100%;
}

.Header {
flex-shrink: 0;
width: 100%;
display: grid;
grid-template-columns: 1fr 3fr 1fr;
align-items: center;
text-align: center;
height: 44px;
padding: 0 20px;
}

.HeaderIconSection {
display: flex;
gap: 4px;
justify-content: end;
}

.Body {
flex-grow: 1;
overflow: hidden;
position: relative;
}

.Name {
font-size: 24px;
font-weight: 600;
margin: 24px 0;
padding: 0 20px;
}

.ContentWrapper {
padding: 20px 20px 0;
}
16 changes: 16 additions & 0 deletions src/pages/shared_profile/SharedProfilePage.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Meta, StoryObj } from '@storybook/react';
import { SharedProfilePage } from './SharedProfilePage';
import { MyProfileProvider } from 'src/entities/profile/model/myProfileStore';
import { fullProfileMock } from '../../entities/profile/api/__mock__/fullProfile.mock';

const meta: Meta<typeof SharedProfilePage> = {
component: SharedProfilePage,
};

export default meta;
type Story = StoryObj<typeof SharedProfilePage>;

export const Default: Story = {
args: {},
decorators: [(fn) => <MyProfileProvider initialState={fullProfileMock}>{fn()}</MyProfileProvider>],
};
46 changes: 46 additions & 0 deletions src/pages/shared_profile/SharedProfilePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { calculateAge, convertDateObjectToDate } from 'src/shared/vo/date';
import styles from './SharedProfilePage.module.css';
import { ScrollView } from 'src/shared/ui/ScrollView/ScrollView';
import { useInView } from 'react-intersection-observer';
import { useMyProfileStore } from 'src/entities/profile/model/myProfileStore';
import { MyProfileView } from '../../entities/profile/ui/MyProfile/MyProfile';
import { Header } from '../../shared/ui/layout/Header/Header';
import { useTranslation } from 'react-i18next';
import { ImageLayout } from '../../shared/ui/ImageLayout/ImageLayout';

export const SharedProfilePage = () => {
const { t } = useTranslation();
const { ref, inView } = useInView();

const profile = useMyProfileStore((state) => state);
const age = calculateAge(convertDateObjectToDate(profile.birthDate));

const urls = [
'/images/googoo_1.png',
'/images/googoo_2.gif',
'/images/googoo_3.png',
'/images/googoo_4.png',
'/images/logo.png',
]; // useDataUrlListFromFiles(profile.images);

return (
<div className={styles.Wrapper}>
{inView ? (
<span />
) : (
<Header prefixSlot={<></>} suffixSlot={<></>}>
{profile.name}({t(profile.gender)}, {age})
</Header>
)}
<ScrollView rootClassName={styles.Body}>
<ImageLayout urls={urls} />
<h1 className={styles.Name} ref={ref}>
{profile.name}({profile.gender}, {age})
</h1>
<div className={styles.ContentWrapper}>
<MyProfileView profile={profile} initialOpen={true} />
</div>
</ScrollView>
</div>
);
};
43 changes: 43 additions & 0 deletions src/shared/ui/ImageLayout/ImageLayout.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

.ImageLayout {
width: 100%;
background-color: var(--color-neutral-10);

display: grid;
overflow: hidden;

& img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
}

&[data-itemcount='5'], &[data-itemcount='4'] {
grid: 1fr 1fr / 2fr 1fr 1fr;

& img:nth-child(1) {
grid-row: 1 / span 2;
}
}

&[data-itemcount='3'] {
grid: 1fr 1fr / 2fr 1fr;

& img:nth-child(1) {
grid-row: 1 / span 2;
}
}

&[data-itemcount='2'] {
grid-template-columns: 1fr 1fr;
}

&[data-itemcount='1'] {
height: 50vw;

& img {
height: 100%;
}
}
}
11 changes: 11 additions & 0 deletions src/shared/ui/ImageLayout/ImageLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import styles from './ImageLayout.module.css';

export const ImageLayout = ({ urls }: { urls: string[] }) => {
return (
<div className={styles.ImageLayout} data-itemcount={Math.min(urls.length, 5)}>
{urls.map((url) => (
<img key={url} src={url} alt={'프로필 이미지'} />
))}
</div>
);
};

0 comments on commit 9a75843

Please sign in to comment.