diff --git a/Hosting/src/Data.ts b/Hosting/src/Data.ts index 5a068c5..d882947 100644 --- a/Hosting/src/Data.ts +++ b/Hosting/src/Data.ts @@ -46,6 +46,8 @@ export async function getCreatorData(user: User) { const creatorUrl = getCreatorStorageUrl(userId); const creator: Creator = { name: '', + profile: '', + links: [], products: [], exhibits: [], }; @@ -67,6 +69,8 @@ export async function getCreatorData(user: User) { console.debug('docSnap.data:', data); creator.name = data.name ?? ''; + creator.profile = data.profile ?? ''; + creator.links = data.links ?? []; // 発表作品 const fbProducts = data.products ?? []; @@ -114,6 +118,8 @@ export async function setCreatorData(user: User, data: Creator) { ); await setDoc(docRef, { name: data.name, + profile: data.profile, + links: data.links, products: data.products.map(x => ({ id: x.id, title: x.title, @@ -314,6 +320,12 @@ export interface Creator { /** 表示名 */ name: string; + /** プロフィール */ + profile: string; + + /** SNSリンク */ + links: string[]; + /** 発表作品一覧 */ products: Product[]; diff --git a/Hosting/src/components/pages/Mypage.tsx b/Hosting/src/components/pages/Mypage.tsx index e634ab5..3e62948 100644 --- a/Hosting/src/components/pages/Mypage.tsx +++ b/Hosting/src/components/pages/Mypage.tsx @@ -31,26 +31,28 @@ export const Mypage = () => { const { user } = useAuthContext(); const [creator, setCreator] = useState(); const [loading, setLoading] = useState(true); + const [isSubmitting, setIsSubmitting] = useState(false); + const [addLink, setAddLink] = useState(''); + const [addLinkError, setAddLinkError] = useState(false); const [visibleProductPopup, setVisibleProductPopup] = useState(false); const [visibleExhibitPopup, setVisibleExhibitPopup] = useState(false); - const [isSubmitting, setIsSubmitting] = useState(false); const [editExhibit, setEditExhibit] = useState(); const [editProduct, setEditProduct] = useState(); useEffect(() => { - // データの取得 if (user === null) { return; } - getCreatorData(user) - .then(x => { - setCreator(x); - setLoading(false); - }) - .catch((x: unknown) => { - console.error('failed fetch data: ', x); - }); + void (async () => { + // データの取得 + const creator = await getCreatorData(user); + setCreator(creator); + + setLoading(false); + })().catch((e: unknown) => { + console.error('failed fetch data: ', e); + }); }, [user]); const { @@ -64,8 +66,29 @@ export const Mypage = () => { return

Now loading...

; } + const isValidUrl = (url: string) => { + if (!url) return true; + + try { + new URL(url); + return true; + } catch { + return false; + } + }; + + const onAddLink = () => { + if (creator === undefined) return; + if (addLinkError) return; + + const links = [...creator.links, addLink]; + setCreator({ ...creator, links }); + setAddLink(''); + }; + const onValid: SubmitHandler = async data => { // 一時データの結合 + data.links = creator?.links ?? []; data.products = creator?.products ?? []; data.exhibits = creator?.exhibits ?? []; @@ -98,6 +121,81 @@ export const Mypage = () => { {...register('name', { required: '1文字以上の入力が必要です。' })} /> +
+

プロフィール

+