지금까지 기본으로 필요했던 필수 기능들을 모두 구현하고 맡았던 페이지의 디자인들을 구현하였다.
제작 메인페이지 (갤러리)
제작 메인화면페이지(메인사진, 폰트선택)
제작 인사말페이지
마이페이지
quill 텍스트에디터 사용한 부분의 align 을 적용시키기 위해 global.css에서 로직을 작성해주어 해당 html 부분이 align반영이 될 수 있도록 해주었다.
.quill-preview p {
text-align: left;
}
.ql-align-center {
text-align: center;
}
.ql-align-right {
text-align: right;
}
제작 페이지에서 선택한 폰트가 적용되게 하기 위해 미리보기 페이지에서
invitation 폼을 받아와 invitation.main_photo_info.fontName 에 저장되어 있는 폰트를 받아와 청첩장의 모든 텍스트에 폰트가 적용될 수 있도록 제일 바깥 div에서 적용시켜주었다.
import { notFound } from 'next/navigation';
import { supabase } from '@/utils/supabase/createClient';
import { convertToCamelCase } from '@/utils/convert/invitaitonTypeConvert';
import { convertOrderToComponent } from '@/utils/convert/convertOrderToComponent';
import { Fragment } from 'react';
export const generateStaticParams = async () => {
const { data } = await supabase.from('invitation').select('id');
return (
data?.map((invitation) => ({
id: invitation.id,
})) || []
);
};
const fetchInvitationData = async (id: string) => {
const { data, error } = await supabase.from('invitation').select('*').eq('id', id).single();
if (error || !data) notFound();
return data;
};
const CardPage = async ({ params }: { params: { id: string } }) => {
const invitation = await fetchInvitationData(params.id);
const { isPrivate, renderOrder, ...invitationData } = convertToCamelCase(invitation);
const fontStyle = invitation.main_photo_info.fontName;
console.log(fontStyle);
return isPrivate ? (
<div>아직 공개되지 않은 청첩장입니다.</div>
) : (
<div className={`flex flex-col gap-[56px] font-${fontStyle}`}>
{renderOrder
.sort((a, b) => a.order - b.order)
.map(({ typeOnSharedCard }, index) => (
<Fragment key={index}>{convertOrderToComponent(typeOnSharedCard, invitationData)}</Fragment>
))}
</div>
);
};
export default CardPage;