diff --git a/products/frontend/src/routes/Profile/components/SocialLink/index.module.css b/products/frontend/src/routes/Profile/components/SocialLink/index.module.css new file mode 100644 index 0000000..bc767c2 --- /dev/null +++ b/products/frontend/src/routes/Profile/components/SocialLink/index.module.css @@ -0,0 +1,65 @@ +.title { + text-align: center; + font-size: var(--text-2xl); + margin: var(--space-2xl) 0 var(--space-xl) 0; +} + +.accountContainer { + display: flex; + gap: var(--space-2xl); + width: fit-content; + margin: 20px auto 20px auto; + border: 1px solid var(--color-base); + border-radius: 10px; + padding: var(--space-sm) var(--space-base); +} + +@media screen and (min-width: 600px) { + .accountContainer { + display: flex; + gap: var(--space-2xl); + } +} + +@media screen and (max-width: 599px) { + .accountContainer { + display: flex; + gap: var(--space-lg); + flex-direction: column; + align-items: center; + } +} + +.iconWrapper { + display: flex; + width: 150px; + gap: var(--space-sm); +} + +.icon { + width: 50px; + height: 50px; + fill: var(--color-base); +} + +.iconLabel { + display: flex; + align-items: center; + font-size: var(--text-xl); +} + +.button { + font-size: var(--color-base); + color: var(--background-color-base); + background-color: var(--color-base); + border: none; + padding: 0 var(--space-sm); + border-radius: 10px; + cursor: pointer; + height: 50px; +} + +.button:disabled { + background-color: var(--color-disabled); + cursor: not-allowed; +} diff --git a/products/frontend/src/routes/Profile/components/SocialLink/index.tsx b/products/frontend/src/routes/Profile/components/SocialLink/index.tsx new file mode 100644 index 0000000..625e0b1 --- /dev/null +++ b/products/frontend/src/routes/Profile/components/SocialLink/index.tsx @@ -0,0 +1,85 @@ +import { useEffect, useState, type FC } from 'react'; +// better-auth +import { authClient } from '../../../../lib/auth'; +// icons +import { FaDiscord, FaGoogle } from 'react-icons/fa6'; +// css +import styles from './index.module.css'; + +type Provider = 'discord' | 'google'; +type LinkedSocialAccount = { + provider: Provider; + isLinked: boolean; +}; + +const SocialLink: FC = () => { + const [linkedAccounts, setLinkedAccounts] = useState([]); + + useEffect(() => { + const fetchSession = async () => { + const session = await authClient.listAccounts(); + if (session.data) { + for (const account of session.data) { + setLinkedAccounts((prev) => [ + ...prev, + { provider: account.providerId as 'discord' | 'google', isLinked: true }, + ]); + } + } else { + console.log('No linked accounts found.'); + } + }; + fetchSession(); + }, []); + + const handleDiscordLinkSocial = async () => { + await authClient.linkSocial({ + provider: 'discord', + callbackURL: `${import.meta.env.VITE_REDIRECT_URL satisfies string}profile`, + }); + }; + const handleGoogleLinkSocial = async () => { + await authClient.linkSocial({ + provider: 'google', + callbackURL: `${import.meta.env.VITE_REDIRECT_URL satisfies string}profile`, + }); + }; + + return ( + <> +

アカウント連携

+
+
+ +

Discord

+
+ {linkedAccounts.find((account) => account.provider === 'discord' && account.isLinked) ? ( + + ) : ( + + )} +
+
+
+ +

Google

+
+ {linkedAccounts.find((account) => account.provider === 'google' && account.isLinked) ? ( + + ) : ( + + )} +
+ + ); +}; + +export default SocialLink; diff --git a/products/frontend/src/routes/Profile/components/index.ts b/products/frontend/src/routes/Profile/components/index.ts new file mode 100644 index 0000000..c1052a3 --- /dev/null +++ b/products/frontend/src/routes/Profile/components/index.ts @@ -0,0 +1 @@ +export { default as SocialLink } from './SocialLink'; diff --git a/products/frontend/src/routes/Profile/index.tsx b/products/frontend/src/routes/Profile/index.tsx index b1524ba..93456e4 100644 --- a/products/frontend/src/routes/Profile/index.tsx +++ b/products/frontend/src/routes/Profile/index.tsx @@ -9,6 +9,8 @@ import { useForm, type SubmitHandler } from 'react-hook-form'; import { FormButton, Loading, Error, Title } from '../../share'; // toast import { toast } from 'react-hot-toast'; +// components +import { SocialLink } from './components'; // css import styles from './index.module.css'; @@ -91,6 +93,7 @@ const Profile: FC = () => { + )}