grid-flow-row auto-rows-fr gap-5 p-4 mt-8`}>
<% loginMethods.forEach(authType => { %>
<% if (authType !== "Social Logins") { %>
<%-`<${authType.replaceAll(' ', '')} token={token} setToken={setToken} />`-%>
diff --git a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/MagicDashboardRedirect.tsx b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
index 2225998..4c2cbed 100644
--- a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
+++ b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
@@ -1,6 +1,9 @@
import React, { useCallback } from 'react';
-import Spacer from '../ui/Spacer';
import DevLinks from './DevLinks';
+import Image from 'next/image';
+import Info from 'public/info.svg';
+import Link from 'public/link_white.svg';
+import Logo from 'public/logo.svg';
const MagicDashboardRedirect = () => {
const onClick = useCallback(() => {
@@ -9,18 +12,27 @@ const MagicDashboardRedirect = () => {
return (
-
-
-
-
- Please set your NEXT_PUBLIC_MAGIC_API_KEY
environment variable in .env
. You can get
- your Magic API key from the Magic Dashboard.
-
+
-
-
-
diff --git a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Facebook.tsx b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Facebook.tsx
index 4e9f1c0..17bd3a1 100644
--- a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Facebook.tsx
+++ b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Facebook.tsx
@@ -55,18 +55,16 @@ const Facebook = ({ token, setToken }: LoginProps) => {
) : (
-
0 ? 'cursor-default' : 'cursor-pointer',
- )}
+
{
if (token.length == 0) login();
}}
+ disabled={false}
>
-
- Facebook
-
+
+
Continue with Facebook
+
)}
diff --git a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Github.tsx b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Github.tsx
index e527a3e..8004de7 100644
--- a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Github.tsx
+++ b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Github.tsx
@@ -55,18 +55,16 @@ const Github = ({ token, setToken }: LoginProps) => {
) : (
-
0 ? 'cursor-default' : 'cursor-pointer',
- )}
+
{
if (token.length == 0) login();
}}
+ disabled={false}
>
-
- Github
-
+
+
Continue with Github
+
)}
diff --git a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Google.tsx b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Google.tsx
index 324e347..4dc8087 100644
--- a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Google.tsx
+++ b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Google.tsx
@@ -55,18 +55,16 @@ const Google = ({ token, setToken }: LoginProps) => {
) : (
-
0 ? 'cursor-default' : 'cursor-pointer',
- )}
+
{
if (token.length == 0) login();
}}
+ disabled={false}
>
-
- Google
-
+
+
Continue with Google
+
)}
diff --git a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/SMSOTP.tsx b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/SMSOTP.tsx
index 68adc0c..2b3e474 100644
--- a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/SMSOTP.tsx
+++ b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/SMSOTP.tsx
@@ -74,7 +74,7 @@ const SMSOTP = ({ token, setToken }: LoginProps) => {
disabled={isLoginInProgress || (token.length > 0 ? false : phone.length == 0)}
onClick={() => handleLogin()}
>
- {isLoginInProgress ?
: 'Login'}
+ {isLoginInProgress ?
: 'Log in / Sign up'}
diff --git a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Twitch.tsx b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Twitch.tsx
index fe7af2c..8986ba7 100644
--- a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Twitch.tsx
+++ b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Twitch.tsx
@@ -55,18 +55,16 @@ const Twitch = ({ token, setToken }: LoginProps) => {
) : (
-
0 ? 'cursor-default' : 'cursor-pointer',
- )}
+
{
if (token.length == 0) login();
}}
+ disabled={false}
>
-
- Twitch
-
+
+
Continue with Twitch
+
)}
diff --git a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Twitter.tsx b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Twitter.tsx
index a7c12e3..f90a7a2 100644
--- a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Twitter.tsx
+++ b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/auth/Twitter.tsx
@@ -55,18 +55,16 @@ const Twitter = ({ token, setToken }: LoginProps) => {
) : (
-
0 ? 'cursor-default' : 'cursor-pointer',
- )}
+
{
if (token.length == 0) login();
}}
+ disabled={false}
>
-
- Twitter
-
+
+
Continue with Twitter
+
)}
diff --git a/scaffolds/nextjs-dedicated-wallet/template/src/styles/globals.css b/scaffolds/nextjs-dedicated-wallet/template/src/styles/globals.css
index 83bde73..7222af2 100644
--- a/scaffolds/nextjs-dedicated-wallet/template/src/styles/globals.css
+++ b/scaffolds/nextjs-dedicated-wallet/template/src/styles/globals.css
@@ -47,7 +47,7 @@ ul {
}
.nft-name {
- @apply text-black font-semibold;
+ @apply font-semibold text-black;
font-family: 'Inter';
}
@@ -60,7 +60,7 @@ ul {
}
.cards-container {
- @apply mt-[-250px] relative;
+ @apply relative top-[30px] md:top-[-60px] lg:top-[-60px];
}
@media only screen and (max-width: 767px) {
@@ -70,7 +70,7 @@ ul {
}
.network-dropdown {
- @apply w-fit m-auto rounded-xl;
+ @apply m-auto w-fit rounded-xl;
}
.active-network {
@@ -116,7 +116,7 @@ ul {
@apply flex flex-col items-center min-h-screen bg-gray-300;
}
.login-method-grid {
- @apply w-[100%] grid grid-cols-4 gap-5 p-4;
+ @apply max-w-[100%] grid-rows-3 gap-5 p-4 mt-8;
}
.login-method-grid-item-container {
@@ -125,7 +125,7 @@ ul {
.login-button {
@apply w-full h-12 text-white font-semibold text-base leading-6 transition-[0.1s] text-center transition-[0.1s] m-auto px-2 py-3 rounded-[300px] border-[none];
- background: #a799ff;
+ background: #8271f3;
}
.login-button:disabled {
@@ -142,7 +142,7 @@ ul {
}
.links {
- @apply flex justify-center text-white font-semibold mt-5 mb-3 mx-auto;
+ @apply flex justify-center mx-auto mt-5 text-sm mb-3 font-semibold text-white;
}
.link {
@apply transition-[0.1s] px-[30px] py-0;
@@ -163,7 +163,7 @@ ul {
@apply cursor-pointer;
}
.link-divider {
- @apply h-5 w-px;
+ @apply w-px h-5;
}
.footer-links {
@@ -221,7 +221,7 @@ ul {
@apply w-[50px] text-center flex items-center justify-center cursor-default;
}
.loading {
- @apply animate-spin cursor-default;
+ @apply cursor-default animate-spin;
}
@keyframes rotation {
@@ -234,18 +234,18 @@ ul {
}
.card {
- @apply w-[300px] flex flex-col shadow-[0px_4px_24px_rgba(49,49,49,0.1)] mt-0 mb-[27px] mx-auto px-6 py-8 rounded-2xl bg-[#ffffff];
+ @apply w-[344px] flex flex-col shadow-[0px_4px_24px_rgba(49,49,49,0.1)] mt-0 mb-[27px] mx-auto px-6 py-8 rounded-2xl bg-[#ffffff];
}
.card-header {
@apply text-xl font-semibold text-left mt-0 mb-[25px];
}
.card-label-container {
- @apply flex justify-between items-center mb-3;
+ @apply flex items-center justify-between mb-3;
}
.card-label {
- @apply text-sm font-medium cursor-pointer;
+ @apply text-sm font-medium cursor-pointer;
}
.toast {
@apply fixed w-fit text-white font-medium shadow-[4px_8px_20px_rgba(0,0,0,0.15)] mx-auto my-0 px-4 py-2 rounded-[10px] top-[30px] inset-x-0 bg-[#00875f];
@@ -291,10 +291,35 @@ a {
}
.app-header-container {
- @apply block pt-4 w-full drop-shadow-[0_35px_35px_rgba(0,0,0,0.25)] min-h-[30vh] flex flex-col items-center bg-magic block;
+ @apply block w-full drop-shadow-[0_35px_35px_rgba(0,0,0,0.25)] min-h-[40%] flex-col gap-2.5 p-8 items-center bg-[url('/login_bg.png')] bg-cover bg-no-repeat pb-20;
text-align: -webkit-center;
}
.redirect-container {
- @apply flex flex-col items-center min-h-screen bg-[length:100%_auto] bg-[url('/background.svg')];
+ @apply flex flex-col items-center h-screen bg-center bg-cover bg-no-repeat bg-[url('/redirect_bg.png')];
+}
+
+.redirect-card {
+ @apply bg-[#F8F8FA] rounded-[10px] shadow-[0px_4px_24px_rgba(49,49,49,0.1)] p-2 m-12;
+}
+
+.social-login-button {
+ @apply flex flex-row min-w-[296px] h-12 text-[#3C4043] transition-[0.1s] px-6 py-3 rounded-[300px] bg-[#ffffff] border-2 border-[#DADCE0] relative top-16;
+}
+
+.social-login-button:disabled {
+ @apply opacity-50;
+}
+
+.social-login-button:hover:enabled {
+ @apply cursor-pointer;
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #ffffff;
+}
+.social-login-button:active:enabled {
+ @apply opacity-50 scale-[0.99];
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #ffffff;
+}
+
+.api-button {
+ @apply bg-[#6844bc] text-[#FFFFFF] flex w-[280px] justify-center items-center h-12 font-semibold text-base leading-6 transition-[0.1s] px-6 py-3 rounded-[300px] border-[none];
}
diff --git a/scaffolds/nextjs-dedicated-wallet/template/tailwind.config.js b/scaffolds/nextjs-dedicated-wallet/template/tailwind.config.js
index 1da1a7e..0fc0404 100644
--- a/scaffolds/nextjs-dedicated-wallet/template/tailwind.config.js
+++ b/scaffolds/nextjs-dedicated-wallet/template/tailwind.config.js
@@ -1,19 +1,17 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
- content: [
- './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
- './src/components/**/*.{js,ts,jsx,tsx,mdx}',
- './src/app/**/*.{js,ts,jsx,tsx,mdx}',
- ],
- theme: {
- extend: {
- backgroundImage: {
- magic: "url('../../public//background.svg')",
- 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
- 'gradient-conic':
- 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
- },
- },
- },
- plugins: [],
-}
+ content: [
+ './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
+ './src/components/**/*.{js,ts,jsx,tsx,mdx}',
+ './src/app/**/*.{js,ts,jsx,tsx,mdx}',
+ ],
+ theme: {
+ extend: {
+ backgroundImage: {
+ 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
+ 'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
+ },
+ },
+ },
+ plugins: [],
+};
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/scaffold.tsx b/scaffolds/nextjs-flow-dedicated-wallet/scaffold.tsx
index 24a724c..8f1886e 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/scaffold.tsx
+++ b/scaffolds/nextjs-flow-dedicated-wallet/scaffold.tsx
@@ -1,6 +1,6 @@
import { Flags } from 'core/flags';
import BaseScaffold from 'core/types/BaseScaffold';
-import { AuthTypePrompt, BlockchainNetworkPrompt, NpmClientPrompt, PublishableApiKeyPrompt } from 'scaffolds/prompts';
+import { AuthTypePrompt, NpmClientPrompt, PublishableApiKeyPrompt } from 'scaffolds/prompts';
export type Data = NpmClientPrompt.Data & PublishableApiKeyPrompt.Data & AuthTypePrompt.Data;
@@ -21,10 +21,13 @@ export default class FlowDedicatedScaffold extends BaseScaffold {
public installationCommand: string[] = ['npm', 'install'];
public startCommand: string[] = ['npm', 'run', 'dev'];
public source: string | string[] = [
- './public/background.svg',
'./public/favicon.ico',
- './public/magic_color_white.svg',
+ './public/logo.svg',
+ './public/info.svg',
'./public/link.svg',
+ './public/link_white.svg',
+ './public/redirect_bg.png',
+ './public/login_bg.png',
'./.env.example',
'./.eslintrc.json',
'./.gitignore',
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/public/background.svg b/scaffolds/nextjs-flow-dedicated-wallet/template/public/background.svg
deleted file mode 100644
index c611daa..0000000
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/public/background.svg
+++ /dev/null
@@ -1,32 +0,0 @@
-
\ No newline at end of file
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/public/info.svg b/scaffolds/nextjs-flow-dedicated-wallet/template/public/info.svg
new file mode 100644
index 0000000..df6edb9
--- /dev/null
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/public/info.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/public/link_white.svg b/scaffolds/nextjs-flow-dedicated-wallet/template/public/link_white.svg
new file mode 100644
index 0000000..c87852b
--- /dev/null
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/public/link_white.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/public/login_bg.png b/scaffolds/nextjs-flow-dedicated-wallet/template/public/login_bg.png
new file mode 100644
index 0000000..a4021c4
Binary files /dev/null and b/scaffolds/nextjs-flow-dedicated-wallet/template/public/login_bg.png differ
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/public/logo.svg b/scaffolds/nextjs-flow-dedicated-wallet/template/public/logo.svg
new file mode 100644
index 0000000..e13da68
--- /dev/null
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/public/logo.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/public/magic_color_white.svg b/scaffolds/nextjs-flow-dedicated-wallet/template/public/magic_color_white.svg
deleted file mode 100644
index 3267c05..0000000
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/public/magic_color_white.svg
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/public/redirect_bg.png b/scaffolds/nextjs-flow-dedicated-wallet/template/public/redirect_bg.png
new file mode 100644
index 0000000..aa322ee
Binary files /dev/null and b/scaffolds/nextjs-flow-dedicated-wallet/template/public/redirect_bg.png differ
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/Dashboard.tsx b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/Dashboard.tsx
index 25a067a..4e02d36 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/Dashboard.tsx
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/Dashboard.tsx
@@ -1,27 +1,25 @@
-import React from 'react'
-import WalletMethods from './cards/WalletMethodsCard'
-import SendTransaction from './cards/SendTransactionCard'
-import Spacer from '@/components/ui/Spacer'
-import {LoginProps} from '@/utils/types'
-import UserInfo from './cards/UserInfoCard'
-import DevLinks from './DevLinks'
-import Header from './Header'
+import React from 'react';
+import WalletMethods from './cards/WalletMethodsCard';
+import SendTransaction from './cards/SendTransactionCard';
+import Spacer from '@/components/ui/Spacer';
+import { LoginProps } from '@/utils/types';
+import UserInfo from './cards/UserInfoCard';
+import DevLinks from './DevLinks';
+import Header from './Header';
-export default function Dashboard({token, setToken}: LoginProps) {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
+export default function Dashboard({ token, setToken }: LoginProps) {
+ return (
+
+ );
}
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/Header.tsx b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/Header.tsx
index b997a10..b02dbb1 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/Header.tsx
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/Header.tsx
@@ -1,19 +1,16 @@
-import Image from 'next/image'
-import MagicColorWhite from 'public/magic_color_white.svg'
-import {Dispatch, SetStateAction} from 'react'
-import DevLinks from './DevLinks'
+import Image from 'next/image';
+import MagicLogo from 'public/logo.svg';
+import DevLinks from './DevLinks';
const Header = () => {
- return (
-
-
-
-
- )
-}
+ return (
+
+ );
+};
-export default Header
+export default Header;
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/Login.tsx b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/Login.tsx
index a2ba0ba..9cac8d6 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/Login.tsx
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/Login.tsx
@@ -1,22 +1,22 @@
-import {LoginProps} from '@/utils/types'
+import { LoginProps } from '@/utils/types'
import Header from './Header'
<% loginMethods.forEach(authType => { %>
<%-`import ${authType.replaceAll(' ', '')} from './auth/${authType.replaceAll(' ', '')}';`-%>
<% }) %>
-const Login = ({token, setToken}: LoginProps) => {
- return (
-
-
-
- <% loginMethods.forEach(authType => { %>
- <% if (authType !== "Social Logins") { %>
- <%-`<${authType.replaceAll(' ', '')} token={token} setToken={setToken} />`-%>
- <% } %>
- <% }) %>
-
-
- )
+const Login = ({ token, setToken }: LoginProps) => {
+ return (
+
+
+
grid-flow-row auto-rows-fr gap-5 p-4 mt-8`}>
+ <% loginMethods.forEach(authType => { %>
+ <% if (authType !== "Social Logins") { %>
+ <%-`<${authType.replaceAll(' ', '')} token={token} setToken={setToken} />`-%>
+ <% } %>
+ <% }) %>
+
+
+ )
}
export default Login
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/MagicDashboardRedirect.tsx b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
index 3c0eb04..4c2cbed 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
@@ -1,35 +1,43 @@
-import React, {useCallback} from 'react'
-import Spacer from '../ui/Spacer'
-import Header from './Header'
-import DevLinks from './DevLinks'
+import React, { useCallback } from 'react';
+import DevLinks from './DevLinks';
+import Image from 'next/image';
+import Info from 'public/info.svg';
+import Link from 'public/link_white.svg';
+import Logo from 'public/logo.svg';
const MagicDashboardRedirect = () => {
- const onClick = useCallback(() => {
- window.open('https://dashboard.magic.link/signup', '_blank')
- }, [])
+ const onClick = useCallback(() => {
+ window.open('https://dashboard.magic.link/signup', '_blank');
+ }, []);
- return (
-
-
-
-
-
- Please set your NEXT_PUBLIC_MAGIC_API_KEY
{' '}
- environment variable in .env
. You can get your
- Magic API key from the Magic Dashboard.
-
-
-
-
-
- Go to Dashboard
-
-
-
-
- )
-}
+ return (
+
+
+
+
+
+
+
+ Please set your NEXT_PUBLIC_MAGIC_API_KEY
environment variable in .env
. You can
+ get your Magic API key from the Magic Dashboard.
+
+
+
-export default MagicDashboardRedirect
+
+ Get API keys
+
+
+
+
+
+ );
+};
+
+export default MagicDashboardRedirect;
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Discord.tsx b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Discord.tsx
index d05c653..763aed7 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Discord.tsx
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Discord.tsx
@@ -1,81 +1,73 @@
-import {LoginProps} from '@/utils/types'
-import {useMagic} from '../MagicProvider'
-import {useEffect, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '@/components/ui/Spinner'
-import classNames from 'classnames'
-import Image from 'next/image'
-import discord from 'public/social/Discord.svg'
-import Card from '@/components/ui/Card'
-import CardHeader from '@/components/ui/CardHeader'
+import { LoginProps } from '@/utils/types';
+import { useMagic } from '../MagicProvider';
+import { useEffect, useState } from 'react';
+import { saveToken } from '@/utils/common';
+import Spinner from '@/components/ui/Spinner';
+import classNames from 'classnames';
+import Image from 'next/image';
+import discord from 'public/social/Discord.svg';
+import Card from '@/components/ui/Card';
+import CardHeader from '@/components/ui/CardHeader';
-const Discord = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [isAuthLoading, setIsAuthLoading] = useState
(null)
+const Discord = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [isAuthLoading, setIsAuthLoading] = useState(null);
- useEffect(() => {
- setIsAuthLoading(localStorage.getItem('isAuthLoading'))
- }, [])
+ useEffect(() => {
+ setIsAuthLoading(localStorage.getItem('isAuthLoading'));
+ }, []);
- useEffect(() => {
- const checkLogin = async () => {
- try {
- if (magic) {
- const result = await magic?.oauth.getRedirectResult()
- //do stuff with user profile data
- saveToken(result.magic.idToken, setToken, 'SOCIAL')
- setLoadingFlag('false')
- }
- } catch (e) {
- console.log('social login error: ' + e)
- setLoadingFlag('false')
- }
- }
+ useEffect(() => {
+ const checkLogin = async () => {
+ try {
+ if (magic) {
+ const result = await magic?.oauth.getRedirectResult();
+ //do stuff with user profile data
+ saveToken(result.magic.idToken, setToken, 'SOCIAL');
+ setLoadingFlag('false');
+ }
+ } catch (e) {
+ console.log('social login error: ' + e);
+ setLoadingFlag('false');
+ }
+ };
- checkLogin()
- }, [magic, setToken])
+ checkLogin();
+ }, [magic, setToken]);
- const login = async () => {
- setLoadingFlag('true')
- await magic?.oauth.loginWithRedirect({
- provider: 'discord',
- redirectURI: window.location.origin,
- })
- }
+ const login = async () => {
+ setLoadingFlag('true');
+ await magic?.oauth.loginWithRedirect({
+ provider: 'discord',
+ redirectURI: window.location.origin,
+ });
+ };
- const setLoadingFlag = (loading: string) => {
- localStorage.setItem('isAuthLoading', loading)
- setIsAuthLoading(loading)
- }
+ const setLoadingFlag = (loading: string) => {
+ localStorage.setItem('isAuthLoading', loading);
+ setIsAuthLoading(loading);
+ };
- return (
-
- Discord Login
- {isAuthLoading && isAuthLoading !== 'false' ? (
-
- ) : (
-
-
0
- ? 'cursor-default'
- : 'cursor-pointer'
- )}
- onClick={() => {
- if (token.length == 0) login()
- }}>
-
-
Discord
-
-
- )}
-
- )
-}
-export default Discord
+ return (
+
+ Discord Login
+ {isAuthLoading && isAuthLoading !== 'false' ? (
+
+ ) : (
+
+
{
+ if (token.length == 0) login();
+ }}
+ disabled={false}
+ >
+
+ Continue with Discord
+
+
+ )}
+
+ );
+};
+export default Discord;
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/EmailOTP.tsx b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/EmailOTP.tsx
index 3327f6b..662e77c 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/EmailOTP.tsx
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/EmailOTP.tsx
@@ -1,90 +1,78 @@
-import {useMagic} from '../MagicProvider'
-import showToast from '@/utils/showToast'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import {RPCError, RPCErrorCode} from 'magic-sdk'
-import {LoginProps} from '@/utils/types'
-import {saveToken} from '@/utils/common'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
-import {useState} from 'react'
-import FormInput from '@/components/ui/FormInput'
+import { useMagic } from '../MagicProvider';
+import showToast from '@/utils/showToast';
+import Spinner from '../../ui/Spinner';
+import { RPCError, RPCErrorCode } from 'magic-sdk';
+import { LoginProps } from '@/utils/types';
+import { saveToken } from '@/utils/common';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
+import { useState } from 'react';
+import FormInput from '@/components/ui/FormInput';
-const EmailOTP = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [email, setEmail] = useState('')
- const [emailError, setEmailError] = useState(false)
- const [isLoginInProgress, setLoginInProgress] = useState(false)
+const EmailOTP = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [email, setEmail] = useState('');
+ const [emailError, setEmailError] = useState(false);
+ const [isLoginInProgress, setLoginInProgress] = useState(false);
- const handleLogin = async () => {
- if (
- !email.match(
- /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/
- )
- ) {
- setEmailError(true)
- } else {
- try {
- setLoginInProgress(true)
- setEmailError(false)
- const account = await magic?.auth.loginWithEmailOTP({email})
- if (account) {
- saveToken(account, setToken, 'EMAIL')
- setEmail('')
- }
- } catch (e) {
- console.log('login error: ' + JSON.stringify(e))
- if (e instanceof RPCError) {
- switch (e.code) {
- case RPCErrorCode.MagicLinkFailedVerification:
- case RPCErrorCode.MagicLinkExpired:
- case RPCErrorCode.MagicLinkRateLimited:
- case RPCErrorCode.UserAlreadyLoggedIn:
- showToast({message: e.message, type: 'error'})
- break
- default:
- showToast({
- message:
- 'Something went wrong. Please try again',
- type: 'error',
- })
- }
- }
- } finally {
- setLoginInProgress(false)
- }
- }
- }
+ const handleLogin = async () => {
+ if (!email.match(/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/)) {
+ setEmailError(true);
+ } else {
+ try {
+ setLoginInProgress(true);
+ setEmailError(false);
+ const account = await magic?.auth.loginWithEmailOTP({ email });
+ if (account) {
+ saveToken(account, setToken, 'EMAIL');
+ setEmail('');
+ }
+ } catch (e) {
+ console.log('login error: ' + JSON.stringify(e));
+ if (e instanceof RPCError) {
+ switch (e.code) {
+ case RPCErrorCode.MagicLinkFailedVerification:
+ case RPCErrorCode.MagicLinkExpired:
+ case RPCErrorCode.MagicLinkRateLimited:
+ case RPCErrorCode.UserAlreadyLoggedIn:
+ showToast({ message: e.message, type: 'error' });
+ break;
+ default:
+ showToast({
+ message: 'Something went wrong. Please try again',
+ type: 'error',
+ });
+ }
+ }
+ } finally {
+ setLoginInProgress(false);
+ }
+ }
+ };
- return (
-
- Email OTP Login
-
- {
- if (emailError) setEmailError(false)
- setEmail(e.target.value)
- }}
- placeholder={
- token.length > 0 ? 'Already logged in' : 'Email'
- }
- value={email}
- />
- {emailError && (
- Enter a valid email
- )}
- 0 ? false : email.length == 0)
- }
- onClick={() => handleLogin()}>
- {isLoginInProgress ? : 'Login'}
-
-
-
- )
-}
+ return (
+
+ Email OTP Login
+
+ {
+ if (emailError) setEmailError(false);
+ setEmail(e.target.value);
+ }}
+ placeholder={token.length > 0 ? 'Already logged in' : 'Email'}
+ value={email}
+ />
+ {emailError && Enter a valid email}
+ 0 ? false : email.length == 0)}
+ onClick={() => handleLogin()}
+ >
+ {isLoginInProgress ? : 'Log in / Sign up'}
+
+
+
+ );
+};
-export default EmailOTP
+export default EmailOTP;
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Facebook.tsx b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Facebook.tsx
index 107761a..17bd3a1 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Facebook.tsx
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Facebook.tsx
@@ -1,81 +1,73 @@
-import {LoginProps} from '@/utils/types'
-import {useMagic} from '../MagicProvider'
-import {useEffect, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import Image from 'next/image'
-import facebook from 'public/social/Facebook.svg'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
+import { LoginProps } from '@/utils/types';
+import { useMagic } from '../MagicProvider';
+import { useEffect, useState } from 'react';
+import { saveToken } from '@/utils/common';
+import Spinner from '../../ui/Spinner';
+import classNames from 'classnames';
+import Image from 'next/image';
+import facebook from 'public/social/Facebook.svg';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
-const Facebook = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [isAuthLoading, setIsAuthLoading] = useState(null)
+const Facebook = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [isAuthLoading, setIsAuthLoading] = useState(null);
- useEffect(() => {
- setIsAuthLoading(localStorage.getItem('isAuthLoading'))
- }, [])
+ useEffect(() => {
+ setIsAuthLoading(localStorage.getItem('isAuthLoading'));
+ }, []);
- useEffect(() => {
- const checkLogin = async () => {
- try {
- if (magic) {
- const result = await magic?.oauth.getRedirectResult()
- //do stuff with user profile data
- saveToken(result.magic.idToken, setToken, 'SOCIAL')
- setLoadingFlag('false')
- }
- } catch (e) {
- console.log('social login error: ' + e)
- setLoadingFlag('false')
- }
- }
+ useEffect(() => {
+ const checkLogin = async () => {
+ try {
+ if (magic) {
+ const result = await magic?.oauth.getRedirectResult();
+ //do stuff with user profile data
+ saveToken(result.magic.idToken, setToken, 'SOCIAL');
+ setLoadingFlag('false');
+ }
+ } catch (e) {
+ console.log('social login error: ' + e);
+ setLoadingFlag('false');
+ }
+ };
- checkLogin()
- }, [magic, setToken])
+ checkLogin();
+ }, [magic, setToken]);
- const login = async () => {
- setLoadingFlag('true')
- await magic?.oauth.loginWithRedirect({
- provider: 'facebook',
- redirectURI: window.location.origin,
- })
- }
+ const login = async () => {
+ setLoadingFlag('true');
+ await magic?.oauth.loginWithRedirect({
+ provider: 'facebook',
+ redirectURI: window.location.origin,
+ });
+ };
- const setLoadingFlag = (loading: string) => {
- localStorage.setItem('isAuthLoading', loading)
- setIsAuthLoading(loading)
- }
+ const setLoadingFlag = (loading: string) => {
+ localStorage.setItem('isAuthLoading', loading);
+ setIsAuthLoading(loading);
+ };
- return (
-
- Facebook Login
- {isAuthLoading && isAuthLoading !== 'false' ? (
-
- ) : (
-
-
0
- ? 'cursor-default'
- : 'cursor-pointer'
- )}
- onClick={() => {
- if (token.length == 0) login()
- }}>
-
-
Facebook
-
-
- )}
-
- )
-}
-export default Facebook
+ return (
+
+ Facebook Login
+ {isAuthLoading && isAuthLoading !== 'false' ? (
+
+ ) : (
+
+
{
+ if (token.length == 0) login();
+ }}
+ disabled={false}
+ >
+
+ Continue with Facebook
+
+
+ )}
+
+ );
+};
+export default Facebook;
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Github.tsx b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Github.tsx
index 431fd34..8004de7 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Github.tsx
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Github.tsx
@@ -1,81 +1,73 @@
-import {LoginProps} from '@/utils/types'
-import {useMagic} from '../MagicProvider'
-import {useEffect, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import Image from 'next/image'
-import github from 'public/social/Github.svg'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
+import { LoginProps } from '@/utils/types';
+import { useMagic } from '../MagicProvider';
+import { useEffect, useState } from 'react';
+import { saveToken } from '@/utils/common';
+import Spinner from '../../ui/Spinner';
+import classNames from 'classnames';
+import Image from 'next/image';
+import github from 'public/social/Github.svg';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
-const Github = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [isAuthLoading, setIsAuthLoading] = useState(null)
+const Github = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [isAuthLoading, setIsAuthLoading] = useState(null);
- useEffect(() => {
- setIsAuthLoading(localStorage.getItem('isAuthLoading'))
- }, [])
+ useEffect(() => {
+ setIsAuthLoading(localStorage.getItem('isAuthLoading'));
+ }, []);
- useEffect(() => {
- const checkLogin = async () => {
- try {
- if (magic) {
- const result = await magic?.oauth.getRedirectResult()
- //do stuff with user profile data
- saveToken(result.magic.idToken, setToken, 'SOCIAL')
- setLoadingFlag('false')
- }
- } catch (e) {
- console.log('social login error: ' + e)
- setLoadingFlag('false')
- }
- }
+ useEffect(() => {
+ const checkLogin = async () => {
+ try {
+ if (magic) {
+ const result = await magic?.oauth.getRedirectResult();
+ //do stuff with user profile data
+ saveToken(result.magic.idToken, setToken, 'SOCIAL');
+ setLoadingFlag('false');
+ }
+ } catch (e) {
+ console.log('social login error: ' + e);
+ setLoadingFlag('false');
+ }
+ };
- checkLogin()
- }, [magic, setToken])
+ checkLogin();
+ }, [magic, setToken]);
- const login = async () => {
- setLoadingFlag('true')
- await magic?.oauth.loginWithRedirect({
- provider: 'github',
- redirectURI: window.location.origin,
- })
- }
+ const login = async () => {
+ setLoadingFlag('true');
+ await magic?.oauth.loginWithRedirect({
+ provider: 'github',
+ redirectURI: window.location.origin,
+ });
+ };
- const setLoadingFlag = (loading: string) => {
- localStorage.setItem('isAuthLoading', loading)
- setIsAuthLoading(loading)
- }
+ const setLoadingFlag = (loading: string) => {
+ localStorage.setItem('isAuthLoading', loading);
+ setIsAuthLoading(loading);
+ };
- return (
-
- Github Login
- {isAuthLoading && isAuthLoading !== 'false' ? (
-
- ) : (
-
-
0
- ? 'cursor-default'
- : 'cursor-pointer'
- )}
- onClick={() => {
- if (token.length == 0) login()
- }}>
-
-
Github
-
-
- )}
-
- )
-}
-export default Github
+ return (
+
+ Github Login
+ {isAuthLoading && isAuthLoading !== 'false' ? (
+
+ ) : (
+
+
{
+ if (token.length == 0) login();
+ }}
+ disabled={false}
+ >
+
+ Continue with Github
+
+
+ )}
+
+ );
+};
+export default Github;
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Google.tsx b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Google.tsx
index 29ab572..4dc8087 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Google.tsx
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Google.tsx
@@ -1,81 +1,73 @@
-import {LoginProps} from '@/utils/types'
-import {useMagic} from '../MagicProvider'
-import {useEffect, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import Image from 'next/image'
-import google from 'public/social/Google.svg'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
+import { LoginProps } from '@/utils/types';
+import { useMagic } from '../MagicProvider';
+import { useEffect, useState } from 'react';
+import { saveToken } from '@/utils/common';
+import Spinner from '../../ui/Spinner';
+import classNames from 'classnames';
+import Image from 'next/image';
+import google from 'public/social/Google.svg';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
-const Google = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [isAuthLoading, setIsAuthLoading] = useState(null)
+const Google = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [isAuthLoading, setIsAuthLoading] = useState(null);
- useEffect(() => {
- setIsAuthLoading(localStorage.getItem('isAuthLoading'))
- }, [])
+ useEffect(() => {
+ setIsAuthLoading(localStorage.getItem('isAuthLoading'));
+ }, []);
- useEffect(() => {
- const checkLogin = async () => {
- try {
- if (magic) {
- const result = await magic?.oauth.getRedirectResult()
- //do stuff with user profile data
- saveToken(result.magic.idToken, setToken, 'SOCIAL')
- setLoadingFlag('false')
- }
- } catch (e) {
- console.log('social login error: ' + e)
- setLoadingFlag('false')
- }
- }
+ useEffect(() => {
+ const checkLogin = async () => {
+ try {
+ if (magic) {
+ const result = await magic?.oauth.getRedirectResult();
+ //do stuff with user profile data
+ saveToken(result.magic.idToken, setToken, 'SOCIAL');
+ setLoadingFlag('false');
+ }
+ } catch (e) {
+ console.log('social login error: ' + e);
+ setLoadingFlag('false');
+ }
+ };
- checkLogin()
- }, [magic, setToken])
+ checkLogin();
+ }, [magic, setToken]);
- const login = async () => {
- setLoadingFlag('true')
- await magic?.oauth.loginWithRedirect({
- provider: 'google',
- redirectURI: window.location.origin,
- })
- }
+ const login = async () => {
+ setLoadingFlag('true');
+ await magic?.oauth.loginWithRedirect({
+ provider: 'google',
+ redirectURI: window.location.origin,
+ });
+ };
- const setLoadingFlag = (loading: string) => {
- localStorage.setItem('isAuthLoading', loading)
- setIsAuthLoading(loading)
- }
+ const setLoadingFlag = (loading: string) => {
+ localStorage.setItem('isAuthLoading', loading);
+ setIsAuthLoading(loading);
+ };
- return (
-
- Google Login
- {isAuthLoading && isAuthLoading !== 'false' ? (
-
- ) : (
-
-
0
- ? 'cursor-default'
- : 'cursor-pointer'
- )}
- onClick={() => {
- if (token.length == 0) login()
- }}>
-
-
Google
-
-
- )}
-
- )
-}
-export default Google
+ return (
+
+ Google Login
+ {isAuthLoading && isAuthLoading !== 'false' ? (
+
+ ) : (
+
+
{
+ if (token.length == 0) login();
+ }}
+ disabled={false}
+ >
+
+ Continue with Google
+
+
+ )}
+
+ );
+};
+export default Google;
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/LoginForm.tsx b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/LoginForm.tsx
deleted file mode 100644
index 80a53f2..0000000
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/LoginForm.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import {LoginProps} from '@/utils/types'
-import {useEffect, useMemo, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '../../ui/Spinner'
-import {useRouter} from 'next/router'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
-
-const setScriptAttributesAndAddScript = (src: string) => {
- const script = document.createElement('script')
- script.src = src
- script.setAttribute(
- 'data-magic-publishable-api-key',
- process.env.NEXT_PUBLIC_MAGIC_API_KEY!
- )
- script.setAttribute('data-redirect-uri', '/')
- script.async = true
-
- document.body.appendChild(script)
-}
-
-const LoginForm = ({token, setToken}: LoginProps) => {
- const router = useRouter()
- const [isLoginInProgress, setLoginInProgress] = useState(false)
-
- useMemo(async () => {
- if (token.length == 0 && router.query) {
- if (router.query.didt) {
- await saveToken(router.query.didt as string, setToken, 'FORM')
- router.replace('/', undefined, {shallow: true})
- }
- if (router.query.magic_credential) {
- await saveToken(
- router.query.magic_credential as string,
- setToken,
- 'FORM'
- )
- router.replace('/', undefined, {shallow: true})
- }
- }
- }, [router, setToken, token.length])
-
- useEffect(() => {
- if (token.length > 0 && !isLoginInProgress) {
- setLoginInProgress(false)
- }
- }, [token, setLoginInProgress, isLoginInProgress])
-
- const handleLogin = () => {
- setLoginInProgress(true)
- setScriptAttributesAndAddScript('https://auth.magic.link/pnp/login')
- }
-
- return (
-
- Login Form
- handleLogin()}>
- {isLoginInProgress ? : 'Login'}
-
-
- Please wait a few seconds after clicking login as this button is
- executing a magic script
-
-
- )
-}
-
-export default LoginForm
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/SMSOTP.tsx b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/SMSOTP.tsx
index 239e4ac..2b3e474 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/SMSOTP.tsx
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/SMSOTP.tsx
@@ -1,90 +1,84 @@
-import {useState} from 'react'
-import {useMagic} from '../MagicProvider'
-import showToast from '@/utils/showToast'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import {RPCError, RPCErrorCode} from 'magic-sdk'
-import {LoginProps} from '@/utils/types'
-import {saveToken} from '@/utils/common'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
-import FormInput from '@/components/ui/FormInput'
+import { useState } from 'react';
+import { useMagic } from '../MagicProvider';
+import showToast from '@/utils/showToast';
+import Spinner from '../../ui/Spinner';
+import { RPCError, RPCErrorCode } from 'magic-sdk';
+import { LoginProps } from '@/utils/types';
+import { saveToken } from '@/utils/common';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
+import FormInput from '@/components/ui/FormInput';
-const SMSOTP = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [phone, setPhone] = useState('')
- const [phoneError, setPhoneError] = useState(false)
- const [isLoginInProgress, setLoginInProgress] = useState(false)
+const SMSOTP = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [phone, setPhone] = useState('');
+ const [phoneError, setPhoneError] = useState(false);
+ const [isLoginInProgress, setLoginInProgress] = useState(false);
- const handleLogin = async () => {
- if (!phone.match(/^\+?\d{10,14}$/)) {
- setPhoneError(true)
- } else {
- try {
- setLoginInProgress(true)
- setPhoneError(false)
- const account = await magic?.auth.loginWithSMS({
- phoneNumber: phone,
- })
- if (account) {
- saveToken(account, setToken, 'SMS')
- setPhone('')
- }
- } catch (e) {
- console.log('login error: ' + JSON.stringify(e))
- if (e instanceof RPCError) {
- switch (e.code) {
- case RPCErrorCode.MagicLinkFailedVerification:
- case RPCErrorCode.MagicLinkExpired:
- case RPCErrorCode.MagicLinkRateLimited:
- case RPCErrorCode.UserAlreadyLoggedIn:
- showToast({message: e.message, type: 'error'})
- break
- default:
- showToast({
- message:
- 'Something went wrong. Please try again',
- type: 'error',
- })
- }
- }
- } finally {
- setLoginInProgress(false)
- }
- }
- }
+ const handleLogin = async () => {
+ if (!phone.match(/^\+?\d{10,14}$/)) {
+ setPhoneError(true);
+ } else {
+ try {
+ setLoginInProgress(true);
+ setPhoneError(false);
+ const account = await magic?.auth.loginWithSMS({
+ phoneNumber: phone,
+ });
+ if (account) {
+ saveToken(account, setToken, 'SMS');
+ setPhone('');
+ }
+ } catch (e) {
+ console.log('login error: ' + JSON.stringify(e));
+ if (e instanceof RPCError) {
+ switch (e.code) {
+ case RPCErrorCode.MagicLinkFailedVerification:
+ case RPCErrorCode.MagicLinkExpired:
+ case RPCErrorCode.MagicLinkRateLimited:
+ case RPCErrorCode.UserAlreadyLoggedIn:
+ showToast({ message: e.message, type: 'error' });
+ break;
+ default:
+ showToast({
+ message: 'Something went wrong. Please try again',
+ type: 'error',
+ });
+ }
+ }
+ } finally {
+ setLoginInProgress(false);
+ }
+ }
+ };
- return (
-
- SMS Login
-
- {
- if (phoneError) setPhoneError(false)
- setPhone(e.target.value)
- }}
- placeholder={
- token.length > 0 ? 'Already logged in' : '+11234567890'
- }
- value={phone}
- />
- {phoneError && (
-
- Enter a valid phone number
-
- )}
- 0 ? false : phone.length == 0)
- }
- onClick={() => handleLogin()}>
- {isLoginInProgress ? : 'Login'}
-
-
-
- )
-}
+ return (
+
+ SMS Login
+
+ {
+ if (phoneError) setPhoneError(false);
+ setPhone(e.target.value);
+ }}
+ placeholder={token.length > 0 ? 'Already logged in' : '+11234567890'}
+ value={phone}
+ />
+ {phoneError && (
+
+ Enter a valid phone number
+
+ )}
+ 0 ? false : phone.length == 0)}
+ onClick={() => handleLogin()}
+ >
+ {isLoginInProgress ? : 'Log in / Sign up'}
+
+
+
+ );
+};
-export default SMSOTP
+export default SMSOTP;
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Twitch.tsx b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Twitch.tsx
index 3f03e01..8986ba7 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Twitch.tsx
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Twitch.tsx
@@ -1,81 +1,73 @@
-import {LoginProps} from '@/utils/types'
-import {useMagic} from '../MagicProvider'
-import {useEffect, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import Image from 'next/image'
-import twitch from 'public/social/Twitch.svg'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
+import { LoginProps } from '@/utils/types';
+import { useMagic } from '../MagicProvider';
+import { useEffect, useState } from 'react';
+import { saveToken } from '@/utils/common';
+import Spinner from '../../ui/Spinner';
+import classNames from 'classnames';
+import Image from 'next/image';
+import twitch from 'public/social/Twitch.svg';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
-const Twitch = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [isAuthLoading, setIsAuthLoading] = useState(null)
+const Twitch = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [isAuthLoading, setIsAuthLoading] = useState(null);
- useEffect(() => {
- setIsAuthLoading(localStorage.getItem('isAuthLoading'))
- }, [])
+ useEffect(() => {
+ setIsAuthLoading(localStorage.getItem('isAuthLoading'));
+ }, []);
- useEffect(() => {
- const checkLogin = async () => {
- try {
- if (magic) {
- const result = await magic?.oauth.getRedirectResult()
- //do stuff with user profile data
- saveToken(result.magic.idToken, setToken, 'SOCIAL')
- setLoadingFlag('false')
- }
- } catch (e) {
- console.log('social login error: ' + e)
- setLoadingFlag('false')
- }
- }
+ useEffect(() => {
+ const checkLogin = async () => {
+ try {
+ if (magic) {
+ const result = await magic?.oauth.getRedirectResult();
+ //do stuff with user profile data
+ saveToken(result.magic.idToken, setToken, 'SOCIAL');
+ setLoadingFlag('false');
+ }
+ } catch (e) {
+ console.log('social login error: ' + e);
+ setLoadingFlag('false');
+ }
+ };
- checkLogin()
- }, [magic, setToken])
+ checkLogin();
+ }, [magic, setToken]);
- const login = async () => {
- setLoadingFlag('true')
- await magic?.oauth.loginWithRedirect({
- provider: 'twitch',
- redirectURI: window.location.origin,
- })
- }
+ const login = async () => {
+ setLoadingFlag('true');
+ await magic?.oauth.loginWithRedirect({
+ provider: 'twitch',
+ redirectURI: window.location.origin,
+ });
+ };
- const setLoadingFlag = (loading: string) => {
- localStorage.setItem('isAuthLoading', loading)
- setIsAuthLoading(loading)
- }
+ const setLoadingFlag = (loading: string) => {
+ localStorage.setItem('isAuthLoading', loading);
+ setIsAuthLoading(loading);
+ };
- return (
-
- Twitch Login
- {isAuthLoading && isAuthLoading !== 'false' ? (
-
- ) : (
-
-
0
- ? 'cursor-default'
- : 'cursor-pointer'
- )}
- onClick={() => {
- if (token.length == 0) login()
- }}>
-
-
Twitch
-
-
- )}
-
- )
-}
-export default Twitch
+ return (
+
+ Twitch Login
+ {isAuthLoading && isAuthLoading !== 'false' ? (
+
+ ) : (
+
+
{
+ if (token.length == 0) login();
+ }}
+ disabled={false}
+ >
+
+ Continue with Twitch
+
+
+ )}
+
+ );
+};
+export default Twitch;
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Twitter.tsx b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Twitter.tsx
index d60db9e..f90a7a2 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Twitter.tsx
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/src/components/magic/auth/Twitter.tsx
@@ -1,81 +1,73 @@
-import {LoginProps} from '@/utils/types'
-import {useMagic} from '../MagicProvider'
-import {useEffect, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import Image from 'next/image'
-import twitter from 'public/social/Twitter.svg'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
+import { LoginProps } from '@/utils/types';
+import { useMagic } from '../MagicProvider';
+import { useEffect, useState } from 'react';
+import { saveToken } from '@/utils/common';
+import Spinner from '../../ui/Spinner';
+import classNames from 'classnames';
+import Image from 'next/image';
+import twitter from 'public/social/Twitter.svg';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
-const Twitter = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [isAuthLoading, setIsAuthLoading] = useState(null)
+const Twitter = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [isAuthLoading, setIsAuthLoading] = useState(null);
- useEffect(() => {
- setIsAuthLoading(localStorage.getItem('isAuthLoading'))
- }, [])
+ useEffect(() => {
+ setIsAuthLoading(localStorage.getItem('isAuthLoading'));
+ }, []);
- useEffect(() => {
- const checkLogin = async () => {
- try {
- if (magic) {
- const result = await magic?.oauth.getRedirectResult()
- //do stuff with user profile data
- saveToken(result.magic.idToken, setToken, 'SOCIAL')
- setLoadingFlag('false')
- }
- } catch (e) {
- console.log('social login error: ' + e)
- setLoadingFlag('false')
- }
- }
+ useEffect(() => {
+ const checkLogin = async () => {
+ try {
+ if (magic) {
+ const result = await magic?.oauth.getRedirectResult();
+ //do stuff with user profile data
+ saveToken(result.magic.idToken, setToken, 'SOCIAL');
+ setLoadingFlag('false');
+ }
+ } catch (e) {
+ console.log('social login error: ' + e);
+ setLoadingFlag('false');
+ }
+ };
- checkLogin()
- }, [magic, setToken])
+ checkLogin();
+ }, [magic, setToken]);
- const login = async () => {
- setLoadingFlag('true')
- await magic?.oauth.loginWithRedirect({
- provider: 'twitter',
- redirectURI: window.location.origin,
- })
- }
+ const login = async () => {
+ setLoadingFlag('true');
+ await magic?.oauth.loginWithRedirect({
+ provider: 'twitter',
+ redirectURI: window.location.origin,
+ });
+ };
- const setLoadingFlag = (loading: string) => {
- localStorage.setItem('isAuthLoading', loading)
- setIsAuthLoading(loading)
- }
+ const setLoadingFlag = (loading: string) => {
+ localStorage.setItem('isAuthLoading', loading);
+ setIsAuthLoading(loading);
+ };
- return (
-
-
- {isAuthLoading && isAuthLoading !== 'false' ? (
-
- ) : (
-
-
0
- ? 'cursor-default'
- : 'cursor-pointer'
- )}
- onClick={() => {
- if (token.length == 0) login()
- }}>
-
-
Twitter
-
-
- )}
-
- )
-}
-export default Twitter
+ return (
+
+
+ {isAuthLoading && isAuthLoading !== 'false' ? (
+
+ ) : (
+
+
{
+ if (token.length == 0) login();
+ }}
+ disabled={false}
+ >
+
+ Continue with Twitter
+
+
+ )}
+
+ );
+};
+export default Twitter;
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/src/styles/globals.css b/scaffolds/nextjs-flow-dedicated-wallet/template/src/styles/globals.css
index aba4039..7222af2 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/src/styles/globals.css
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/src/styles/globals.css
@@ -5,301 +5,321 @@
@tailwind utilities;
:root {
- --foreground-rgb: 0, 0, 0;
- --background-start-rgb: 214, 219, 220;
- --background-end-rgb: 255, 255, 255;
+ --foreground-rgb: 0, 0, 0;
+ --background-start-rgb: 214, 219, 220;
+ --background-end-rgb: 255, 255, 255;
}
@media (prefers-color-scheme: dark) {
- :root {
- --foreground-rgb: 255, 255, 255;
- --background-start-rgb: 0, 0, 0;
- --background-end-rgb: 0, 0, 0;
- }
+ :root {
+ --foreground-rgb: 255, 255, 255;
+ --background-start-rgb: 0, 0, 0;
+ --background-end-rgb: 0, 0, 0;
+ }
}
html,
body {
- @apply m-0 p-0 bg-[#f8f8fa] scroll-pt-12;
- font-family: 'Inter', sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
+ @apply m-0 p-0 bg-[#f8f8fa] scroll-pt-12;
+ font-family: 'Inter', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
}
nav > ul > li {
- @apply text-left list-none text-[#777679] cursor-pointer mb-[15px];
+ @apply text-left list-none text-[#777679] cursor-pointer mb-[15px];
}
ul {
- @apply w-fit m-0 pl-[30px] pr-0 py-0;
+ @apply w-fit m-0 pl-[30px] pr-0 py-0;
}
.active {
- @apply text-[#6851ff] font-semibold;
+ @apply text-[#6851ff] font-semibold;
}
.active::before {
- @apply content-['\2022'] text-[#6851ff] font-[bold] inline-block w-[1em] ml-[-1em];
+ @apply content-['\2022'] text-[#6851ff] font-[bold] inline-block w-[1em] ml-[-1em];
}
.nft {
- @apply text-[#777679];
+ @apply text-[#777679];
}
.nft-name {
- @apply text-black font-semibold;
- font-family: 'Inter';
+ @apply font-semibold text-black;
+ font-family: 'Inter';
}
.nft-list {
- @apply overflow-auto max-h-[270px];
+ @apply overflow-auto max-h-[270px];
}
.nft:not(:last-child) {
- @apply mb-2.5;
+ @apply mb-2.5;
}
.cards-container {
- @apply mt-[-250px] relative;
+ @apply relative top-[30px] md:top-[-60px] lg:top-[-60px];
}
@media only screen and (max-width: 767px) {
- .cards-container {
- @apply mt-[-89px];
- }
+ .cards-container {
+ @apply mt-[-89px];
+ }
}
.network-dropdown {
- @apply w-fit m-auto rounded-xl;
+ @apply m-auto w-fit rounded-xl;
}
.active-network {
- @apply border w-[264px] flex items-center cursor-pointer justify-between m-auto px-4 py-3 rounded-xl border-solid border-[#dddbe0] bg-[#fff];
+ @apply border w-[264px] flex items-center cursor-pointer justify-between m-auto px-4 py-3 rounded-xl border-solid border-[#dddbe0] bg-[#fff];
}
.active-network::selection {
- @apply bg-transparent;
+ @apply bg-transparent;
}
.rotate {
- @apply rotate-180;
+ @apply rotate-180;
}
.network-options {
- @apply overflow-hidden w-fit border mx-auto my-[5px] px-0 py-[5px] rounded-xl border-solid border-[#dddbe0] bg-[#fff];
+ @apply overflow-hidden w-fit border mx-auto my-[5px] px-0 py-[5px] rounded-xl border-solid border-[#dddbe0] bg-[#fff];
}
.network-dropdown-option {
- @apply w-[264px] flex items-center justify-start transition-[0.1s] m-auto px-4 py-3 bg-[#fff];
+ @apply w-[264px] flex items-center justify-start transition-[0.1s] m-auto px-4 py-3 bg-[#fff];
}
.network-dropdown-option:hover {
- @apply text-white cursor-pointer bg-[#6851ff];
+ @apply text-white cursor-pointer bg-[#6851ff];
}
.network-dropdown-option:active {
- @apply opacity-50;
+ @apply opacity-50;
}
.magic-logo {
- @apply mt-10 mb-[15px] mx-0 text-center;
+ @apply mb-[15px] mx-0 text-center;
}
.demo-sub-header {
- @apply text-[rgba(255,255,255,0.5)] text-xl font-normal m-0;
- font-family: monospace;
+ @apply text-[rgba(255,255,255,0.5)] text-xl font-normal m-0;
+ font-family: monospace;
}
.home-page {
- @apply flex flex-col justify-center items-center min-h-screen relative;
+ @apply flex flex-col justify-center items-center min-h-screen relative bg-[length:100vw_320px] bg-no-repeat bg-[url('/main.svg')];
}
.login-page {
- @apply flex flex-col items-center min-h-screen bg-gray-300;
+ @apply flex flex-col items-center min-h-screen bg-gray-300;
}
.login-method-grid {
- @apply w-[100%] grid grid-cols-4 gap-5 p-4;
+ @apply max-w-[100%] grid-rows-3 gap-5 p-4 mt-8;
}
.login-method-grid-item-container {
- @apply flex flex-col items-center justify-center;
+ @apply flex flex-col items-center justify-center;
}
.login-button {
- @apply w-full h-12 text-white font-semibold text-base leading-6 transition-[0.1s] text-center transition-[0.1s] m-auto px-2 py-3 rounded-[300px] border-[none];
- background: #a799ff;
+ @apply w-full h-12 text-white font-semibold text-base leading-6 transition-[0.1s] text-center transition-[0.1s] m-auto px-2 py-3 rounded-[300px] border-[none];
+ background: #8271f3;
}
.login-button:disabled {
- background: #a799ff;
+ background: #a799ff;
}
.login-button:hover:enabled {
- @apply cursor-pointer;
- background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)),
- #a799ff;
+ @apply cursor-pointer;
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #a799ff;
}
.login-button:active:enabled {
- @apply opacity-50 cursor-pointer scale-[0.99];
- background: #a799ff;
+ @apply opacity-50 cursor-pointer scale-[0.99];
+ background: #a799ff;
}
.links {
- @apply flex justify-center text-white font-semibold mt-5 mb-3 mx-auto;
+ @apply flex justify-center mx-auto mt-5 text-sm mb-3 font-semibold text-white;
}
.link {
- @apply transition-[0.1s] px-[30px] py-0;
+ @apply transition-[0.1s] px-[30px] py-0;
}
@media only screen and (max-width: 420px) {
- .link {
- @apply px-[15px] py-0;
- }
+ .link {
+ @apply px-[15px] py-0;
+ }
}
@media only screen and (max-width: 320px) {
- .link {
- @apply px-[5px] py-0;
- }
+ .link {
+ @apply px-[5px] py-0;
+ }
}
.link > a {
- @apply cursor-pointer;
+ @apply cursor-pointer;
}
.link-divider {
- @apply h-5 w-px;
+ @apply w-px h-5;
}
.footer-links {
- @apply flex items-center absolute w-full mt-[30px] mb-0 mx-auto bottom-10;
+ @apply flex items-center absolute w-full mt-[30px] mb-0 mx-auto bottom-10;
}
.wallet-method-container {
- @apply text-left;
+ @apply text-left;
}
.wallet-method {
- @apply w-fit text-[#522fd4] bg-[#edebff] text-base cursor-pointer font-medium transition-[0.1s] h-8 px-3 py-1.5 rounded-[32px] border-[none];
- font-family: monospace;
+ @apply w-fit text-[#522fd4] bg-[#edebff] text-base cursor-pointer font-medium transition-[0.1s] h-8 px-3 py-1.5 rounded-[32px] border-[none];
+ font-family: monospace;
}
.wallet-method:hover:enabled {
- background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)),
- #edebff;
- background-blend-mode: color-burn, normal;
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #edebff;
+ background-blend-mode: color-burn, normal;
}
.wallet-method:active:enabled {
- @apply opacity-50 scale-[0.99];
- background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)),
- #edebff;
+ @apply opacity-50 scale-[0.99];
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #edebff;
}
.wallet-method-desc {
- @apply text-[#77767a] text-left text-sm mt-2.5;
+ @apply text-[#77767a] text-left text-sm mt-2.5;
}
.form-input {
- @apply box-border flex flex-row items-center w-full h-12 border text-base leading-6 text-[#18171a] mb-[15px] px-4 py-3 rounded-[10px] border-solid border-[#dddbe0];
- background: #ffffff;
+ @apply box-border flex flex-row items-center w-full h-12 border text-base leading-6 text-[#18171a] mb-[15px] px-4 py-3 rounded-[10px] border-solid border-[#dddbe0];
+ background: #ffffff;
}
.form-input::placeholder {
- color: #77767a;
+ color: #77767a;
}
.form-button {
- @apply flex flex-row justify-center items-center w-full h-12 text-[#522fd4] font-semibold text-base leading-6 transition-[0.1s] px-6 py-3 rounded-[300px] border-[none] bg-[#edebff];
+ @apply flex flex-row justify-center items-center w-full h-12 text-[#522fd4] font-semibold text-base leading-6 transition-[0.1s] px-6 py-3 rounded-[300px] border-[none] bg-[#edebff];
}
.form-button:disabled {
- @apply opacity-50;
+ @apply opacity-50;
}
.form-button:hover:enabled {
- @apply cursor-pointer;
- background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)),
- #edebff;
+ @apply cursor-pointer;
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #edebff;
}
.form-button:active:enabled {
- @apply opacity-50 scale-[0.99];
- background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)),
- #edebff;
+ @apply opacity-50 scale-[0.99];
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #edebff;
}
.loading-container {
- @apply w-[50px] text-center flex items-center justify-center cursor-default;
+ @apply w-[50px] text-center flex items-center justify-center cursor-default;
}
.loading {
- @apply animate-spin cursor-default;
+ @apply cursor-default animate-spin;
}
@keyframes rotation {
- 0% {
- transform: rotate(0);
- }
- 100% {
- transform: rotate(360deg);
- }
+ 0% {
+ transform: rotate(0);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
}
.card {
- @apply w-[300px] flex flex-col shadow-[0px_4px_24px_rgba(49,49,49,0.1)] mt-0 mb-[27px] mx-auto px-6 py-8 rounded-2xl bg-[#ffffff];
+ @apply w-[344px] flex flex-col shadow-[0px_4px_24px_rgba(49,49,49,0.1)] mt-0 mb-[27px] mx-auto px-6 py-8 rounded-2xl bg-[#ffffff];
}
.card-header {
- @apply text-xl font-semibold text-left mt-0 mb-[25px];
+ @apply text-xl font-semibold text-left mt-0 mb-[25px];
}
.card-label-container {
- @apply flex justify-between items-center mb-3;
+ @apply flex items-center justify-between mb-3;
}
.card-label {
- @apply text-sm font-medium cursor-pointer;
+ @apply text-sm font-medium cursor-pointer;
}
.toast {
- @apply fixed w-fit text-white font-medium shadow-[4px_8px_20px_rgba(0,0,0,0.15)] mx-auto my-0 px-4 py-2 rounded-[10px] top-[30px] inset-x-0 bg-[#00875f];
+ @apply fixed w-fit text-white font-medium shadow-[4px_8px_20px_rgba(0,0,0,0.15)] mx-auto my-0 px-4 py-2 rounded-[10px] top-[30px] inset-x-0 bg-[#00875f];
}
.action-button {
- @apply font-semibold text-[#6851ff] cursor-pointer transition-[0.1s];
+ @apply font-semibold text-[#6851ff] cursor-pointer transition-[0.1s];
}
.disconnect-button {
- @apply font-semibold text-[#d43100] cursor-pointer transition-[0.1s];
+ @apply font-semibold text-[#d43100] cursor-pointer transition-[0.1s];
}
.action-button:hover,
.disconnect-button:hover {
- @apply opacity-70;
+ @apply opacity-70;
}
.action-button:active,
.disconnect-button:active {
- @apply scale-[0.98];
+ @apply scale-[0.98];
}
.code {
- @apply text-base text-left p-2.5 rounded-[10px];
- font-family: monospace;
- background: #f8f8fa;
- word-wrap: break-word;
+ @apply text-base text-left p-2.5 rounded-[10px];
+ font-family: monospace;
+ background: #f8f8fa;
+ word-wrap: break-word;
}
.error {
- @apply self-start text-xs font-semibold text-red-700 justify-self-start;
+ @apply self-start text-xs font-semibold text-red-700 justify-self-start;
}
.divider {
- @apply mx-0 my-[15px] border-b-[#ededf3] border-b border-solid;
+ @apply mx-0 my-[15px] border-b-[#ededf3] border-b border-solid;
}
.flex-row {
- @apply flex items-center;
+ @apply flex items-center;
}
.green-dot {
- @apply h-1.5 w-1.5 bg-[#00cc8f] mr-2.5 rounded-[50%];
+ @apply h-1.5 w-1.5 bg-[#00cc8f] mr-2.5 rounded-[50%];
}
.connected {
- @apply text-base mx-0 my-[5px];
+ @apply text-base mx-0 my-[5px];
}
a {
- all: unset;
+ all: unset;
}
.app-header-container {
- @apply block w-full drop-shadow-[0_35px_35px_rgba(0,0,0,0.25)] min-h-[30vh] flex flex-col items-center bg-magic block;
- text-align: -webkit-center;
+ @apply block w-full drop-shadow-[0_35px_35px_rgba(0,0,0,0.25)] min-h-[40%] flex-col gap-2.5 p-8 items-center bg-[url('/login_bg.png')] bg-cover bg-no-repeat pb-20;
+ text-align: -webkit-center;
}
.redirect-container {
- @apply flex flex-col items-center min-h-screen bg-[length:100%_auto] bg-[url('/background.svg')];
+ @apply flex flex-col items-center h-screen bg-center bg-cover bg-no-repeat bg-[url('/redirect_bg.png')];
+}
+
+.redirect-card {
+ @apply bg-[#F8F8FA] rounded-[10px] shadow-[0px_4px_24px_rgba(49,49,49,0.1)] p-2 m-12;
+}
+
+.social-login-button {
+ @apply flex flex-row min-w-[296px] h-12 text-[#3C4043] transition-[0.1s] px-6 py-3 rounded-[300px] bg-[#ffffff] border-2 border-[#DADCE0] relative top-16;
+}
+
+.social-login-button:disabled {
+ @apply opacity-50;
+}
+
+.social-login-button:hover:enabled {
+ @apply cursor-pointer;
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #ffffff;
+}
+.social-login-button:active:enabled {
+ @apply opacity-50 scale-[0.99];
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #ffffff;
+}
+
+.api-button {
+ @apply bg-[#6844bc] text-[#FFFFFF] flex w-[280px] justify-center items-center h-12 font-semibold text-base leading-6 transition-[0.1s] px-6 py-3 rounded-[300px] border-[none];
}
diff --git a/scaffolds/nextjs-flow-dedicated-wallet/template/tailwind.config.js b/scaffolds/nextjs-flow-dedicated-wallet/template/tailwind.config.js
index 1da1a7e..0fc0404 100644
--- a/scaffolds/nextjs-flow-dedicated-wallet/template/tailwind.config.js
+++ b/scaffolds/nextjs-flow-dedicated-wallet/template/tailwind.config.js
@@ -1,19 +1,17 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
- content: [
- './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
- './src/components/**/*.{js,ts,jsx,tsx,mdx}',
- './src/app/**/*.{js,ts,jsx,tsx,mdx}',
- ],
- theme: {
- extend: {
- backgroundImage: {
- magic: "url('../../public//background.svg')",
- 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
- 'gradient-conic':
- 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
- },
- },
- },
- plugins: [],
-}
+ content: [
+ './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
+ './src/components/**/*.{js,ts,jsx,tsx,mdx}',
+ './src/app/**/*.{js,ts,jsx,tsx,mdx}',
+ ],
+ theme: {
+ extend: {
+ backgroundImage: {
+ 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
+ 'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
+ },
+ },
+ },
+ plugins: [],
+};
diff --git a/scaffolds/nextjs-flow-universal-wallet/template/public/info.svg b/scaffolds/nextjs-flow-universal-wallet/template/public/info.svg
new file mode 100644
index 0000000..df6edb9
--- /dev/null
+++ b/scaffolds/nextjs-flow-universal-wallet/template/public/info.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/scaffolds/nextjs-flow-universal-wallet/template/public/link_white.svg b/scaffolds/nextjs-flow-universal-wallet/template/public/link_white.svg
new file mode 100644
index 0000000..c87852b
--- /dev/null
+++ b/scaffolds/nextjs-flow-universal-wallet/template/public/link_white.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/scaffolds/nextjs-flow-universal-wallet/template/public/login_bg.png b/scaffolds/nextjs-flow-universal-wallet/template/public/login_bg.png
new file mode 100644
index 0000000..a4021c4
Binary files /dev/null and b/scaffolds/nextjs-flow-universal-wallet/template/public/login_bg.png differ
diff --git a/scaffolds/nextjs-flow-universal-wallet/template/public/logo.svg b/scaffolds/nextjs-flow-universal-wallet/template/public/logo.svg
new file mode 100644
index 0000000..e13da68
--- /dev/null
+++ b/scaffolds/nextjs-flow-universal-wallet/template/public/logo.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/scaffolds/nextjs-flow-universal-wallet/template/public/redirect_bg.png b/scaffolds/nextjs-flow-universal-wallet/template/public/redirect_bg.png
new file mode 100644
index 0000000..aa322ee
Binary files /dev/null and b/scaffolds/nextjs-flow-universal-wallet/template/public/redirect_bg.png differ
diff --git a/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/Links.tsx b/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/DevLinks.tsx
similarity index 100%
rename from scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/Links.tsx
rename to scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/DevLinks.tsx
diff --git a/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/Home.tsx b/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/Home.tsx
index 15cfe85..a1d58de 100644
--- a/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/Home.tsx
+++ b/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/Home.tsx
@@ -1,32 +1,32 @@
-import React from 'react'
-import TableOfContents from '../ui/TableOfContents'
-import AppHeader from '../ui/AppHeader'
-import Wallet from './cards/UserInfoCard'
-import WalletMethods from './cards/WalletMethodsCard'
-import SendTransaction from './cards/SendTransactionsCard'
-import Links from './Links'
-import Spacer from '../ui/Spacer'
+import React from 'react';
+import TableOfContents from '../ui/TableOfContents';
+import AppHeader from '../ui/AppHeader';
+import Wallet from './cards/UserInfoCard';
+import WalletMethods from './cards/WalletMethodsCard';
+import SendTransaction from './cards/SendTransactionsCard';
+import Links from './DevLinks';
+import Spacer from '../ui/Spacer';
interface Props {
- setAccount: React.Dispatch>
+ setAccount: React.Dispatch>;
}
-export default function Home({setAccount}: Props) {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
+export default function Home({ setAccount }: Props) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
}
diff --git a/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/Login.tsx b/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/Login.tsx
index 5c66b6d..0055c1b 100644
--- a/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/Login.tsx
+++ b/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/Login.tsx
@@ -1,42 +1,42 @@
-import React, {useState, useCallback} from 'react'
-import AppHeader from '../ui/AppHeader'
-import Links from './Links'
-import ConnectButton from '../ui/ConnectButton'
-import Spacer from '../ui/Spacer'
-import {useMagicContext} from '@/components/magic/MagicProvider'
+import React, { useState, useCallback } from 'react';
+import AppHeader from '../ui/AppHeader';
+import Links from './DevLinks';
+import ConnectButton from '../ui/ConnectButton';
+import Spacer from '../ui/Spacer';
+import { useMagicContext } from '@/components/magic/MagicProvider';
interface Props {
- setAccount: React.Dispatch>
+ setAccount: React.Dispatch>;
}
-const Login = ({setAccount}: Props) => {
- const [disabled, setDisabled] = useState(false)
- const {magic} = useMagicContext()
+const Login = ({ setAccount }: Props) => {
+ const [disabled, setDisabled] = useState(false);
+ const { magic } = useMagicContext();
- const connect = useCallback(async () => {
- if (!magic) return
- try {
- setDisabled(true)
- const account = await magic.flow.getAccount()
- setDisabled(false)
- console.log('Logged in user:', account)
- localStorage.setItem('user', account)
- setAccount(account)
- } catch (error) {
- setDisabled(false)
- console.error(error)
- }
- }, [magic, setAccount])
+ const connect = useCallback(async () => {
+ if (!magic) return;
+ try {
+ setDisabled(true);
+ const account = await magic.flow.getAccount();
+ setDisabled(false);
+ console.log('Logged in user:', account);
+ localStorage.setItem('user', account);
+ setAccount(account);
+ } catch (error) {
+ setDisabled(false);
+ console.error(error);
+ }
+ }, [magic, setAccount]);
- return (
-
- )
-}
+ return (
+
+ );
+};
-export default Login
+export default Login;
diff --git a/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/MagicDashboardRedirect.tsx b/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
index 97aeede..2478f09 100644
--- a/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
+++ b/scaffolds/nextjs-flow-universal-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
@@ -1,34 +1,43 @@
-import React, {useCallback} from 'react'
-import AppHeader from '../ui/AppHeader'
-import Links from './Links'
-import Spacer from '../ui/Spacer'
+import React, { useCallback } from 'react';
+import Image from 'next/image';
+import Info from 'public/info.svg';
+import Link from 'public/link_white.svg';
+import Logo from 'public/logo.svg';
+import DevLinks from './DevLinks';
const MagicDashboardRedirect = () => {
- const onClick = useCallback(() => {
- window.open('https://dashboard.magic.link/signup', '_blank')
- }, [])
+ const onClick = useCallback(() => {
+ window.open('https://dashboard.magic.link/signup', '_blank');
+ }, []);
- return (
-
-
-
-
-
-
- Please set your NEXT_PUBLIC_MAGIC_API_KEY
{' '}
- environment variable in .env
. You can get your
- Magic API key from the Magic Dashboard.
-
-
-
-
-
- Go to Dashboard
-
-
-
-
- )
-}
+ return (
+
+
+
+
+
+
+
+ Please set your NEXT_PUBLIC_MAGIC_API_KEY
environment variable in .env
. You can
+ get your Magic API key from the Magic Dashboard.
+
+
+
-export default MagicDashboardRedirect
+
+ Get API keys
+
+
+
+
+
+ );
+};
+
+export default MagicDashboardRedirect;
diff --git a/scaffolds/nextjs-flow-universal-wallet/template/src/styles/globals.css b/scaffolds/nextjs-flow-universal-wallet/template/src/styles/globals.css
index f78df5d..aed673d 100644
--- a/scaffolds/nextjs-flow-universal-wallet/template/src/styles/globals.css
+++ b/scaffolds/nextjs-flow-universal-wallet/template/src/styles/globals.css
@@ -5,282 +5,285 @@
html,
body {
- @apply m-0 p-0 bg-[#f8f8fa] scroll-pt-12;
- font-family: 'Inter', sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
+ @apply m-0 p-0 bg-[#f8f8fa] scroll-pt-12;
+ font-family: 'Inter', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
}
.table-of-contents {
- @apply w-[220px] min-w-[220px] self-start sticky max-h-[calc(100vh_-_70px)] overflow-auto mt-0 px-0 py-6 top-0;
- position: -webkit-sticky;
+ @apply w-[220px] min-w-[220px] self-start sticky max-h-[calc(100vh_-_70px)] overflow-auto mt-0 px-0 py-6 top-0;
+ position: -webkit-sticky;
}
nav > ul > li {
- @apply text-left list-none text-[#777679] cursor-pointer mb-[15px];
+ @apply text-left list-none text-[#777679] cursor-pointer mb-[15px];
}
ul {
- @apply w-fit m-0 pl-[30px] pr-0 py-0;
+ @apply w-fit m-0 pl-[30px] pr-0 py-0;
}
.active {
- @apply text-[#6851ff] font-semibold;
+ @apply text-[#6851ff] font-semibold;
}
.active::before {
- @apply content-['\2022'] text-[#6851ff] font-[bold] inline-block w-[1em] ml-[-1em];
+ @apply content-['\2022'] text-[#6851ff] font-[bold] inline-block w-[1em] ml-[-1em];
}
.nft {
- @apply text-[#777679];
+ @apply text-[#777679];
}
.nft-name {
- @apply text-black font-semibold;
- font-family: 'Inter';
+ @apply text-black font-semibold;
+ font-family: 'Inter';
}
.nft-list {
- @apply overflow-auto max-h-[270px];
+ @apply overflow-auto max-h-[270px];
}
.nft:not(:last-child) {
- @apply mb-2.5;
+ @apply mb-2.5;
}
.cards-container {
- @apply mt-[-260px];
+ @apply mt-[-260px];
}
@media only screen and (max-width: 767px) {
- .table-of-contents {
- @apply hidden;
- }
- .cards-container {
- @apply mt-[-89px];
- }
+ .table-of-contents {
+ @apply hidden;
+ }
+ .cards-container {
+ @apply mt-[-89px];
+ }
}
.network-dropdown {
- @apply w-fit m-auto rounded-xl;
+ @apply w-fit m-auto rounded-xl;
}
.active-network {
- @apply border w-[264px] flex items-center cursor-pointer justify-between m-auto px-4 py-3 rounded-xl border-solid border-[#dddbe0] bg-[#fff];
+ @apply border w-[264px] flex items-center cursor-pointer justify-between m-auto px-4 py-3 rounded-xl border-solid border-[#dddbe0] bg-[#fff];
}
.active-network::selection {
- @apply bg-transparent;
+ @apply bg-transparent;
}
.rotate {
- @apply rotate-180;
+ @apply rotate-180;
}
.network-options {
- @apply overflow-hidden w-fit border mx-auto my-[5px] px-0 py-[5px] rounded-xl border-solid border-[#dddbe0] bg-[#fff];
+ @apply overflow-hidden w-fit border mx-auto my-[5px] px-0 py-[5px] rounded-xl border-solid border-[#dddbe0] bg-[#fff];
}
.network-dropdown-option {
- @apply w-[264px] flex items-center justify-start transition-[0.1s] m-auto px-4 py-3 bg-[#fff];
+ @apply w-[264px] flex items-center justify-start transition-[0.1s] m-auto px-4 py-3 bg-[#fff];
}
.network-dropdown-option:hover {
- @apply text-white cursor-pointer bg-[#6851ff];
+ @apply text-white cursor-pointer bg-[#6851ff];
}
.network-dropdown-option:active {
- @apply opacity-50;
+ @apply opacity-50;
}
.magic-logo {
- @apply mb-[15px] mx-0 text-center;
+ @apply mb-[15px] mx-0 text-center;
}
.demo-sub-header {
- @apply text-[rgba(255,255,255,0.5)] text-xl font-normal m-0;
- font-family: monospace;
+ @apply text-[rgba(255,255,255,0.5)] text-xl font-normal m-0;
+ font-family: monospace;
}
.home-page {
- @apply flex flex-col justify-center items-center min-h-screen relative bg-[length:100vw_320px] bg-no-repeat bg-[url('/main.svg')];
+ @apply flex flex-col justify-center items-center min-h-screen relative bg-[length:100vw_320px] bg-no-repeat bg-[url('/main.svg')];
}
.login-page {
- @apply min-h-screen bg-[length:100%_auto] bg-[url('/login.svg')];
+ @apply min-h-screen bg-[length:100%_auto] bg-[url('/login.svg')];
}
.connect-button {
- @apply w-[296px] h-12 text-white font-semibold text-base leading-6 transition-[0.1s] text-center transition-[0.1s] m-auto px-6 py-3 rounded-[300px] border-[none];
- background: rgba(255, 255, 255, 0.1);
+ @apply w-[296px] h-12 text-white font-semibold text-base leading-6 transition-[0.1s] text-center transition-[0.1s] m-auto px-6 py-3 rounded-[300px] border-[none];
+ background: rgba(255, 255, 255, 0.1);
}
.connect-button:hover:enabled {
- @apply cursor-pointer;
- background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)),
- rgba(255, 255, 255, 0.1);
+ @apply cursor-pointer;
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), rgba(255, 255, 255, 0.1);
}
.connect-button:active:enabled {
- @apply opacity-50 cursor-pointer scale-[0.99];
- background: rgba(255, 255, 255, 0.1);
+ @apply opacity-50 cursor-pointer scale-[0.99];
+ background: rgba(255, 255, 255, 0.1);
}
.links {
- @apply flex justify-center text-white font-semibold mt-5 mb-3 mx-auto;
+ @apply flex justify-center text-white font-semibold mt-5 mb-3 mx-auto;
}
.link {
- @apply transition-[0.1s] px-[30px] py-0;
+ @apply transition-[0.1s] px-[30px] py-0;
}
@media only screen and (max-width: 420px) {
- .link {
- @apply px-[15px] py-0;
- }
+ .link {
+ @apply px-[15px] py-0;
+ }
}
@media only screen and (max-width: 320px) {
- .link {
- @apply px-[5px] py-0;
- }
+ .link {
+ @apply px-[5px] py-0;
+ }
}
.link > a {
- @apply cursor-pointer;
+ @apply cursor-pointer;
}
.link-divider {
- @apply h-5 w-px;
+ @apply h-5 w-px;
}
.footer-links {
- @apply flex items-center absolute w-full mt-[30px] mb-0 mx-auto bottom-10;
+ @apply flex items-center absolute w-full mt-[30px] mb-0 mx-auto bottom-10;
}
.wallet-method-container {
- @apply text-left;
+ @apply text-left;
}
.wallet-method {
- @apply w-fit text-[#522fd4] bg-[#edebff] text-base cursor-pointer font-medium transition-[0.1s] h-8 px-3 py-1.5 rounded-[32px] border-[none];
- font-family: monospace;
+ @apply w-fit text-[#522fd4] bg-[#edebff] text-base cursor-pointer font-medium transition-[0.1s] h-8 px-3 py-1.5 rounded-[32px] border-[none];
+ font-family: monospace;
}
.wallet-method:hover:enabled {
- background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)),
- #edebff;
- background-blend-mode: color-burn, normal;
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #edebff;
+ background-blend-mode: color-burn, normal;
}
.wallet-method:active:enabled {
- @apply opacity-50 scale-[0.99];
- background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)),
- #edebff;
+ @apply opacity-50 scale-[0.99];
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #edebff;
}
.wallet-method-desc {
- @apply text-[#77767a] text-left text-sm mt-2.5;
+ @apply text-[#77767a] text-left text-sm mt-2.5;
}
.form-input {
- @apply box-border flex flex-row items-center w-full h-12 border text-base leading-6 text-[#18171a] mb-[15px] px-4 py-3 rounded-[10px] border-solid border-[#dddbe0];
- background: #ffffff;
+ @apply box-border flex flex-row items-center w-full h-12 border text-base leading-6 text-[#18171a] mb-[15px] px-4 py-3 rounded-[10px] border-solid border-[#dddbe0];
+ background: #ffffff;
}
.form-input::placeholder {
- color: #77767a;
+ color: #77767a;
}
.form-button {
- @apply flex flex-row justify-center items-center w-full h-12 text-[#522fd4] font-semibold text-base leading-6 transition-[0.1s] px-6 py-3 rounded-[300px] border-[none] bg-[#edebff];
+ @apply flex flex-row justify-center items-center w-full h-12 text-[#522fd4] font-semibold text-base leading-6 transition-[0.1s] px-6 py-3 rounded-[300px] border-[none] bg-[#edebff];
}
.form-button:disabled {
- @apply opacity-50;
+ @apply opacity-50;
}
.form-button:hover:enabled {
- @apply cursor-pointer;
- background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)),
- #edebff;
+ @apply cursor-pointer;
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #edebff;
}
.form-button:active:enabled {
- @apply opacity-50 scale-[0.99];
- background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)),
- #edebff;
+ @apply opacity-50 scale-[0.99];
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #edebff;
}
.loading-container {
- @apply w-[50px] text-center flex items-center justify-center cursor-default;
+ @apply w-[50px] text-center flex items-center justify-center cursor-default;
}
.loading {
- @apply animate-spin cursor-default;
+ @apply animate-spin cursor-default;
}
@keyframes rotation {
- 0% {
- transform: rotate(0);
- }
- 100% {
- transform: rotate(360deg);
- }
+ 0% {
+ transform: rotate(0);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
}
.card {
- @apply w-[300px] flex flex-col shadow-[0px_4px_24px_rgba(49,49,49,0.1)] mt-0 mb-[27px] mx-auto px-6 py-8 rounded-2xl bg-[#ffffff];
+ @apply w-[300px] flex flex-col shadow-[0px_4px_24px_rgba(49,49,49,0.1)] mt-0 mb-[27px] mx-auto px-6 py-8 rounded-2xl bg-[#ffffff];
}
.card-header {
- @apply text-xl font-semibold text-left mt-0 mb-[25px];
+ @apply text-xl font-semibold text-left mt-0 mb-[25px];
}
.card-label-container {
- @apply flex justify-between items-center mb-3;
+ @apply flex justify-between items-center mb-3;
}
.card-label {
- @apply text-sm font-medium cursor-pointer;
+ @apply text-sm font-medium cursor-pointer;
}
.toast {
- @apply fixed w-fit text-white font-medium shadow-[4px_8px_20px_rgba(0,0,0,0.15)] mx-auto my-0 px-4 py-2 rounded-[10px] top-[30px] inset-x-0 bg-[#00875f];
+ @apply fixed w-fit text-white font-medium shadow-[4px_8px_20px_rgba(0,0,0,0.15)] mx-auto my-0 px-4 py-2 rounded-[10px] top-[30px] inset-x-0 bg-[#00875f];
}
.action-button {
- @apply font-semibold text-[#6851ff] cursor-pointer transition-[0.1s];
+ @apply font-semibold text-[#6851ff] cursor-pointer transition-[0.1s];
}
.disconnect-button {
- @apply font-semibold text-[#d43100] cursor-pointer transition-[0.1s];
+ @apply font-semibold text-[#d43100] cursor-pointer transition-[0.1s];
}
.action-button:hover,
.disconnect-button:hover {
- @apply opacity-70;
+ @apply opacity-70;
}
.action-button:active,
.disconnect-button:active {
- @apply scale-[0.98];
+ @apply scale-[0.98];
}
.code {
- @apply text-base text-left p-2.5 rounded-[10px];
- font-family: monospace;
- background: #f8f8fa;
- word-wrap: break-word;
+ @apply text-base text-left p-2.5 rounded-[10px];
+ font-family: monospace;
+ background: #f8f8fa;
+ word-wrap: break-word;
}
.error {
- @apply text-[#d43100] text-xs text-left -mt-2.5 mb-2.5 mx-0;
+ @apply text-[#d43100] text-xs text-left -mt-2.5 mb-2.5 mx-0;
}
.divider {
- @apply mx-0 my-[15px] border-b-[#ededf3] border-b border-solid;
+ @apply mx-0 my-[15px] border-b-[#ededf3] border-b border-solid;
}
.flex-row {
- @apply flex items-center;
+ @apply flex items-center;
}
.green-dot {
- @apply h-1.5 w-1.5 bg-[#00cc8f] mr-2.5 rounded-[50%];
+ @apply h-1.5 w-1.5 bg-[#00cc8f] mr-2.5 rounded-[50%];
}
.connected {
- @apply text-base mx-0 my-[5px];
+ @apply text-base mx-0 my-[5px];
}
a {
- all: unset;
+ all: unset;
}
.app-header-container {
- @apply block pt-4;
- text-align: -webkit-center;
+ @apply block pt-4;
+ text-align: -webkit-center;
}
.redirect-container {
- @apply flex flex-col items-center min-h-screen bg-['100%_auto'] bg-[url('/login.svg')];
+ @apply flex flex-col items-center min-h-screen bg-['100%_auto'] bg-[url('/login.svg')];
+}
+
+.redirect-card {
+ @apply bg-[#F8F8FA] rounded-[10px] shadow-[0px_4px_24px_rgba(49,49,49,0.1)] p-2 m-12;
+}
+
+.api-button {
+ @apply bg-[#6844bc] text-[#FFFFFF] flex w-[280px] justify-center items-center h-12 font-semibold text-base leading-6 transition-[0.1s] px-6 py-3 rounded-[300px] border-[none];
}
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/scaffold.tsx b/scaffolds/nextjs-solana-dedicated-wallet/scaffold.tsx
index 8df6050..aa54317 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/scaffold.tsx
+++ b/scaffolds/nextjs-solana-dedicated-wallet/scaffold.tsx
@@ -1,6 +1,6 @@
import { Flags } from 'core/flags';
import BaseScaffold from 'core/types/BaseScaffold';
-import { AuthTypePrompt, BlockchainNetworkPrompt, NpmClientPrompt, PublishableApiKeyPrompt } from 'scaffolds/prompts';
+import { AuthTypePrompt, NpmClientPrompt, PublishableApiKeyPrompt } from 'scaffolds/prompts';
export type Data = NpmClientPrompt.Data & PublishableApiKeyPrompt.Data & AuthTypePrompt.Data;
@@ -21,10 +21,13 @@ export default class SolanaDedicatedScaffold extends BaseScaffold {
public installationCommand: string[] = ['npm', 'install'];
public startCommand: string[] = ['npm', 'run', 'dev'];
public source: string | string[] = [
- './public/background.svg',
'./public/favicon.ico',
- './public/magic_color_white.svg',
+ './public/logo.svg',
+ './public/info.svg',
'./public/link.svg',
+ './public/link_white.svg',
+ './public/redirect_bg.png',
+ './public/login_bg.png',
'./.env.example',
'./.eslintrc.json',
'./.gitignore',
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/public/background.svg b/scaffolds/nextjs-solana-dedicated-wallet/template/public/background.svg
deleted file mode 100644
index c611daa..0000000
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/public/background.svg
+++ /dev/null
@@ -1,32 +0,0 @@
-
\ No newline at end of file
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/public/info.svg b/scaffolds/nextjs-solana-dedicated-wallet/template/public/info.svg
new file mode 100644
index 0000000..df6edb9
--- /dev/null
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/public/info.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/public/link_white.svg b/scaffolds/nextjs-solana-dedicated-wallet/template/public/link_white.svg
new file mode 100644
index 0000000..c87852b
--- /dev/null
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/public/link_white.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/public/login_bg.png b/scaffolds/nextjs-solana-dedicated-wallet/template/public/login_bg.png
new file mode 100644
index 0000000..a4021c4
Binary files /dev/null and b/scaffolds/nextjs-solana-dedicated-wallet/template/public/login_bg.png differ
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/public/logo.svg b/scaffolds/nextjs-solana-dedicated-wallet/template/public/logo.svg
new file mode 100644
index 0000000..e13da68
--- /dev/null
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/public/logo.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/public/magic_color_white.svg b/scaffolds/nextjs-solana-dedicated-wallet/template/public/magic_color_white.svg
deleted file mode 100644
index 3267c05..0000000
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/public/magic_color_white.svg
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/public/redirect_bg.png b/scaffolds/nextjs-solana-dedicated-wallet/template/public/redirect_bg.png
new file mode 100644
index 0000000..aa322ee
Binary files /dev/null and b/scaffolds/nextjs-solana-dedicated-wallet/template/public/redirect_bg.png differ
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/Dashboard.tsx b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/Dashboard.tsx
index 25a067a..4e02d36 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/Dashboard.tsx
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/Dashboard.tsx
@@ -1,27 +1,25 @@
-import React from 'react'
-import WalletMethods from './cards/WalletMethodsCard'
-import SendTransaction from './cards/SendTransactionCard'
-import Spacer from '@/components/ui/Spacer'
-import {LoginProps} from '@/utils/types'
-import UserInfo from './cards/UserInfoCard'
-import DevLinks from './DevLinks'
-import Header from './Header'
+import React from 'react';
+import WalletMethods from './cards/WalletMethodsCard';
+import SendTransaction from './cards/SendTransactionCard';
+import Spacer from '@/components/ui/Spacer';
+import { LoginProps } from '@/utils/types';
+import UserInfo from './cards/UserInfoCard';
+import DevLinks from './DevLinks';
+import Header from './Header';
-export default function Dashboard({token, setToken}: LoginProps) {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
+export default function Dashboard({ token, setToken }: LoginProps) {
+ return (
+
+ );
}
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/Header.tsx b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/Header.tsx
index b997a10..a6e4012 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/Header.tsx
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/Header.tsx
@@ -1,19 +1,20 @@
-import Image from 'next/image'
-import MagicColorWhite from 'public/magic_color_white.svg'
-import {Dispatch, SetStateAction} from 'react'
-import DevLinks from './DevLinks'
+import Image from 'next/image';
+import Logo from 'public/logo.svg';
+import DevLinks from './DevLinks';
const Header = () => {
- return (
-
-
-
-
- )
-}
+ return (
+
+ );
+};
-export default Header
+export default Header;
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/Login.tsx b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/Login.tsx
index 185ed38..9cac8d6 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/Login.tsx
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/Login.tsx
@@ -1,22 +1,22 @@
-import {LoginProps} from '@/utils/types'
+import { LoginProps } from '@/utils/types'
import Header from './Header'
<% loginMethods.forEach(authType => { %>
<%-`import ${authType.replaceAll(' ', '')} from './auth/${authType.replaceAll(' ', '')}';`-%>
<% }) %>
-const Login = ({token, setToken}: LoginProps) => {
- return (
-
-
-
- <% loginMethods.forEach(authType => { %>
- <% if (authType !== "Social Logins") { %>
- <%-`<${authType.replaceAll(' ', '')} token={token} setToken={setToken} />`-%>
- <% } %>
- <% }) %>
-
-
- )
+const Login = ({ token, setToken }: LoginProps) => {
+ return (
+
+
+
grid-flow-row auto-rows-fr gap-5 p-4 mt-8`}>
+ <% loginMethods.forEach(authType => { %>
+ <% if (authType !== "Social Logins") { %>
+ <%-`<${authType.replaceAll(' ', '')} token={token} setToken={setToken} />`-%>
+ <% } %>
+ <% }) %>
+
+
+ )
}
export default Login
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/MagicDashboardRedirect.tsx b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
index 6083206..4c2cbed 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
@@ -1,7 +1,9 @@
import React, { useCallback } from 'react';
-import Spacer from '../ui/Spacer';
-import Header from './Header';
import DevLinks from './DevLinks';
+import Image from 'next/image';
+import Info from 'public/info.svg';
+import Link from 'public/link_white.svg';
+import Logo from 'public/logo.svg';
const MagicDashboardRedirect = () => {
const onClick = useCallback(() => {
@@ -10,18 +12,27 @@ const MagicDashboardRedirect = () => {
return (
-
-
-
-
- Please set your NEXT_PUBLIC_MAGIC_API_KEY
environment variable in .env
. You can get
- your Magic API key from the Magic Dashboard.
-
+
-
-
-
- Go to Dashboard
+
+
+
+
+
+ Please set your NEXT_PUBLIC_MAGIC_API_KEY
environment variable in .env
. You can
+ get your Magic API key from the Magic Dashboard.
+
+
+
+
+
+ Get API keys
+
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Discord.tsx b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Discord.tsx
index d05c653..763aed7 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Discord.tsx
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Discord.tsx
@@ -1,81 +1,73 @@
-import {LoginProps} from '@/utils/types'
-import {useMagic} from '../MagicProvider'
-import {useEffect, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '@/components/ui/Spinner'
-import classNames from 'classnames'
-import Image from 'next/image'
-import discord from 'public/social/Discord.svg'
-import Card from '@/components/ui/Card'
-import CardHeader from '@/components/ui/CardHeader'
+import { LoginProps } from '@/utils/types';
+import { useMagic } from '../MagicProvider';
+import { useEffect, useState } from 'react';
+import { saveToken } from '@/utils/common';
+import Spinner from '@/components/ui/Spinner';
+import classNames from 'classnames';
+import Image from 'next/image';
+import discord from 'public/social/Discord.svg';
+import Card from '@/components/ui/Card';
+import CardHeader from '@/components/ui/CardHeader';
-const Discord = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [isAuthLoading, setIsAuthLoading] = useState(null)
+const Discord = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [isAuthLoading, setIsAuthLoading] = useState(null);
- useEffect(() => {
- setIsAuthLoading(localStorage.getItem('isAuthLoading'))
- }, [])
+ useEffect(() => {
+ setIsAuthLoading(localStorage.getItem('isAuthLoading'));
+ }, []);
- useEffect(() => {
- const checkLogin = async () => {
- try {
- if (magic) {
- const result = await magic?.oauth.getRedirectResult()
- //do stuff with user profile data
- saveToken(result.magic.idToken, setToken, 'SOCIAL')
- setLoadingFlag('false')
- }
- } catch (e) {
- console.log('social login error: ' + e)
- setLoadingFlag('false')
- }
- }
+ useEffect(() => {
+ const checkLogin = async () => {
+ try {
+ if (magic) {
+ const result = await magic?.oauth.getRedirectResult();
+ //do stuff with user profile data
+ saveToken(result.magic.idToken, setToken, 'SOCIAL');
+ setLoadingFlag('false');
+ }
+ } catch (e) {
+ console.log('social login error: ' + e);
+ setLoadingFlag('false');
+ }
+ };
- checkLogin()
- }, [magic, setToken])
+ checkLogin();
+ }, [magic, setToken]);
- const login = async () => {
- setLoadingFlag('true')
- await magic?.oauth.loginWithRedirect({
- provider: 'discord',
- redirectURI: window.location.origin,
- })
- }
+ const login = async () => {
+ setLoadingFlag('true');
+ await magic?.oauth.loginWithRedirect({
+ provider: 'discord',
+ redirectURI: window.location.origin,
+ });
+ };
- const setLoadingFlag = (loading: string) => {
- localStorage.setItem('isAuthLoading', loading)
- setIsAuthLoading(loading)
- }
+ const setLoadingFlag = (loading: string) => {
+ localStorage.setItem('isAuthLoading', loading);
+ setIsAuthLoading(loading);
+ };
- return (
-
- Discord Login
- {isAuthLoading && isAuthLoading !== 'false' ? (
-
- ) : (
-
-
0
- ? 'cursor-default'
- : 'cursor-pointer'
- )}
- onClick={() => {
- if (token.length == 0) login()
- }}>
-
-
Discord
-
-
- )}
-
- )
-}
-export default Discord
+ return (
+
+ Discord Login
+ {isAuthLoading && isAuthLoading !== 'false' ? (
+
+ ) : (
+
+
{
+ if (token.length == 0) login();
+ }}
+ disabled={false}
+ >
+
+ Continue with Discord
+
+
+ )}
+
+ );
+};
+export default Discord;
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/EmailOTP.tsx b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/EmailOTP.tsx
index 3327f6b..662e77c 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/EmailOTP.tsx
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/EmailOTP.tsx
@@ -1,90 +1,78 @@
-import {useMagic} from '../MagicProvider'
-import showToast from '@/utils/showToast'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import {RPCError, RPCErrorCode} from 'magic-sdk'
-import {LoginProps} from '@/utils/types'
-import {saveToken} from '@/utils/common'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
-import {useState} from 'react'
-import FormInput from '@/components/ui/FormInput'
+import { useMagic } from '../MagicProvider';
+import showToast from '@/utils/showToast';
+import Spinner from '../../ui/Spinner';
+import { RPCError, RPCErrorCode } from 'magic-sdk';
+import { LoginProps } from '@/utils/types';
+import { saveToken } from '@/utils/common';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
+import { useState } from 'react';
+import FormInput from '@/components/ui/FormInput';
-const EmailOTP = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [email, setEmail] = useState('')
- const [emailError, setEmailError] = useState(false)
- const [isLoginInProgress, setLoginInProgress] = useState(false)
+const EmailOTP = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [email, setEmail] = useState('');
+ const [emailError, setEmailError] = useState(false);
+ const [isLoginInProgress, setLoginInProgress] = useState(false);
- const handleLogin = async () => {
- if (
- !email.match(
- /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/
- )
- ) {
- setEmailError(true)
- } else {
- try {
- setLoginInProgress(true)
- setEmailError(false)
- const account = await magic?.auth.loginWithEmailOTP({email})
- if (account) {
- saveToken(account, setToken, 'EMAIL')
- setEmail('')
- }
- } catch (e) {
- console.log('login error: ' + JSON.stringify(e))
- if (e instanceof RPCError) {
- switch (e.code) {
- case RPCErrorCode.MagicLinkFailedVerification:
- case RPCErrorCode.MagicLinkExpired:
- case RPCErrorCode.MagicLinkRateLimited:
- case RPCErrorCode.UserAlreadyLoggedIn:
- showToast({message: e.message, type: 'error'})
- break
- default:
- showToast({
- message:
- 'Something went wrong. Please try again',
- type: 'error',
- })
- }
- }
- } finally {
- setLoginInProgress(false)
- }
- }
- }
+ const handleLogin = async () => {
+ if (!email.match(/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/)) {
+ setEmailError(true);
+ } else {
+ try {
+ setLoginInProgress(true);
+ setEmailError(false);
+ const account = await magic?.auth.loginWithEmailOTP({ email });
+ if (account) {
+ saveToken(account, setToken, 'EMAIL');
+ setEmail('');
+ }
+ } catch (e) {
+ console.log('login error: ' + JSON.stringify(e));
+ if (e instanceof RPCError) {
+ switch (e.code) {
+ case RPCErrorCode.MagicLinkFailedVerification:
+ case RPCErrorCode.MagicLinkExpired:
+ case RPCErrorCode.MagicLinkRateLimited:
+ case RPCErrorCode.UserAlreadyLoggedIn:
+ showToast({ message: e.message, type: 'error' });
+ break;
+ default:
+ showToast({
+ message: 'Something went wrong. Please try again',
+ type: 'error',
+ });
+ }
+ }
+ } finally {
+ setLoginInProgress(false);
+ }
+ }
+ };
- return (
-
- Email OTP Login
-
- {
- if (emailError) setEmailError(false)
- setEmail(e.target.value)
- }}
- placeholder={
- token.length > 0 ? 'Already logged in' : 'Email'
- }
- value={email}
- />
- {emailError && (
- Enter a valid email
- )}
- 0 ? false : email.length == 0)
- }
- onClick={() => handleLogin()}>
- {isLoginInProgress ? : 'Login'}
-
-
-
- )
-}
+ return (
+
+ Email OTP Login
+
+ {
+ if (emailError) setEmailError(false);
+ setEmail(e.target.value);
+ }}
+ placeholder={token.length > 0 ? 'Already logged in' : 'Email'}
+ value={email}
+ />
+ {emailError && Enter a valid email}
+ 0 ? false : email.length == 0)}
+ onClick={() => handleLogin()}
+ >
+ {isLoginInProgress ? : 'Log in / Sign up'}
+
+
+
+ );
+};
-export default EmailOTP
+export default EmailOTP;
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Facebook.tsx b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Facebook.tsx
index 107761a..17bd3a1 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Facebook.tsx
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Facebook.tsx
@@ -1,81 +1,73 @@
-import {LoginProps} from '@/utils/types'
-import {useMagic} from '../MagicProvider'
-import {useEffect, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import Image from 'next/image'
-import facebook from 'public/social/Facebook.svg'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
+import { LoginProps } from '@/utils/types';
+import { useMagic } from '../MagicProvider';
+import { useEffect, useState } from 'react';
+import { saveToken } from '@/utils/common';
+import Spinner from '../../ui/Spinner';
+import classNames from 'classnames';
+import Image from 'next/image';
+import facebook from 'public/social/Facebook.svg';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
-const Facebook = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [isAuthLoading, setIsAuthLoading] = useState(null)
+const Facebook = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [isAuthLoading, setIsAuthLoading] = useState(null);
- useEffect(() => {
- setIsAuthLoading(localStorage.getItem('isAuthLoading'))
- }, [])
+ useEffect(() => {
+ setIsAuthLoading(localStorage.getItem('isAuthLoading'));
+ }, []);
- useEffect(() => {
- const checkLogin = async () => {
- try {
- if (magic) {
- const result = await magic?.oauth.getRedirectResult()
- //do stuff with user profile data
- saveToken(result.magic.idToken, setToken, 'SOCIAL')
- setLoadingFlag('false')
- }
- } catch (e) {
- console.log('social login error: ' + e)
- setLoadingFlag('false')
- }
- }
+ useEffect(() => {
+ const checkLogin = async () => {
+ try {
+ if (magic) {
+ const result = await magic?.oauth.getRedirectResult();
+ //do stuff with user profile data
+ saveToken(result.magic.idToken, setToken, 'SOCIAL');
+ setLoadingFlag('false');
+ }
+ } catch (e) {
+ console.log('social login error: ' + e);
+ setLoadingFlag('false');
+ }
+ };
- checkLogin()
- }, [magic, setToken])
+ checkLogin();
+ }, [magic, setToken]);
- const login = async () => {
- setLoadingFlag('true')
- await magic?.oauth.loginWithRedirect({
- provider: 'facebook',
- redirectURI: window.location.origin,
- })
- }
+ const login = async () => {
+ setLoadingFlag('true');
+ await magic?.oauth.loginWithRedirect({
+ provider: 'facebook',
+ redirectURI: window.location.origin,
+ });
+ };
- const setLoadingFlag = (loading: string) => {
- localStorage.setItem('isAuthLoading', loading)
- setIsAuthLoading(loading)
- }
+ const setLoadingFlag = (loading: string) => {
+ localStorage.setItem('isAuthLoading', loading);
+ setIsAuthLoading(loading);
+ };
- return (
-
- Facebook Login
- {isAuthLoading && isAuthLoading !== 'false' ? (
-
- ) : (
-
-
0
- ? 'cursor-default'
- : 'cursor-pointer'
- )}
- onClick={() => {
- if (token.length == 0) login()
- }}>
-
-
Facebook
-
-
- )}
-
- )
-}
-export default Facebook
+ return (
+
+ Facebook Login
+ {isAuthLoading && isAuthLoading !== 'false' ? (
+
+ ) : (
+
+
{
+ if (token.length == 0) login();
+ }}
+ disabled={false}
+ >
+
+ Continue with Facebook
+
+
+ )}
+
+ );
+};
+export default Facebook;
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Github.tsx b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Github.tsx
index 431fd34..8004de7 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Github.tsx
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Github.tsx
@@ -1,81 +1,73 @@
-import {LoginProps} from '@/utils/types'
-import {useMagic} from '../MagicProvider'
-import {useEffect, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import Image from 'next/image'
-import github from 'public/social/Github.svg'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
+import { LoginProps } from '@/utils/types';
+import { useMagic } from '../MagicProvider';
+import { useEffect, useState } from 'react';
+import { saveToken } from '@/utils/common';
+import Spinner from '../../ui/Spinner';
+import classNames from 'classnames';
+import Image from 'next/image';
+import github from 'public/social/Github.svg';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
-const Github = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [isAuthLoading, setIsAuthLoading] = useState(null)
+const Github = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [isAuthLoading, setIsAuthLoading] = useState(null);
- useEffect(() => {
- setIsAuthLoading(localStorage.getItem('isAuthLoading'))
- }, [])
+ useEffect(() => {
+ setIsAuthLoading(localStorage.getItem('isAuthLoading'));
+ }, []);
- useEffect(() => {
- const checkLogin = async () => {
- try {
- if (magic) {
- const result = await magic?.oauth.getRedirectResult()
- //do stuff with user profile data
- saveToken(result.magic.idToken, setToken, 'SOCIAL')
- setLoadingFlag('false')
- }
- } catch (e) {
- console.log('social login error: ' + e)
- setLoadingFlag('false')
- }
- }
+ useEffect(() => {
+ const checkLogin = async () => {
+ try {
+ if (magic) {
+ const result = await magic?.oauth.getRedirectResult();
+ //do stuff with user profile data
+ saveToken(result.magic.idToken, setToken, 'SOCIAL');
+ setLoadingFlag('false');
+ }
+ } catch (e) {
+ console.log('social login error: ' + e);
+ setLoadingFlag('false');
+ }
+ };
- checkLogin()
- }, [magic, setToken])
+ checkLogin();
+ }, [magic, setToken]);
- const login = async () => {
- setLoadingFlag('true')
- await magic?.oauth.loginWithRedirect({
- provider: 'github',
- redirectURI: window.location.origin,
- })
- }
+ const login = async () => {
+ setLoadingFlag('true');
+ await magic?.oauth.loginWithRedirect({
+ provider: 'github',
+ redirectURI: window.location.origin,
+ });
+ };
- const setLoadingFlag = (loading: string) => {
- localStorage.setItem('isAuthLoading', loading)
- setIsAuthLoading(loading)
- }
+ const setLoadingFlag = (loading: string) => {
+ localStorage.setItem('isAuthLoading', loading);
+ setIsAuthLoading(loading);
+ };
- return (
-
- Github Login
- {isAuthLoading && isAuthLoading !== 'false' ? (
-
- ) : (
-
-
0
- ? 'cursor-default'
- : 'cursor-pointer'
- )}
- onClick={() => {
- if (token.length == 0) login()
- }}>
-
-
Github
-
-
- )}
-
- )
-}
-export default Github
+ return (
+
+ Github Login
+ {isAuthLoading && isAuthLoading !== 'false' ? (
+
+ ) : (
+
+
{
+ if (token.length == 0) login();
+ }}
+ disabled={false}
+ >
+
+ Continue with Github
+
+
+ )}
+
+ );
+};
+export default Github;
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Google.tsx b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Google.tsx
index 29ab572..4dc8087 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Google.tsx
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Google.tsx
@@ -1,81 +1,73 @@
-import {LoginProps} from '@/utils/types'
-import {useMagic} from '../MagicProvider'
-import {useEffect, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import Image from 'next/image'
-import google from 'public/social/Google.svg'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
+import { LoginProps } from '@/utils/types';
+import { useMagic } from '../MagicProvider';
+import { useEffect, useState } from 'react';
+import { saveToken } from '@/utils/common';
+import Spinner from '../../ui/Spinner';
+import classNames from 'classnames';
+import Image from 'next/image';
+import google from 'public/social/Google.svg';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
-const Google = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [isAuthLoading, setIsAuthLoading] = useState(null)
+const Google = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [isAuthLoading, setIsAuthLoading] = useState(null);
- useEffect(() => {
- setIsAuthLoading(localStorage.getItem('isAuthLoading'))
- }, [])
+ useEffect(() => {
+ setIsAuthLoading(localStorage.getItem('isAuthLoading'));
+ }, []);
- useEffect(() => {
- const checkLogin = async () => {
- try {
- if (magic) {
- const result = await magic?.oauth.getRedirectResult()
- //do stuff with user profile data
- saveToken(result.magic.idToken, setToken, 'SOCIAL')
- setLoadingFlag('false')
- }
- } catch (e) {
- console.log('social login error: ' + e)
- setLoadingFlag('false')
- }
- }
+ useEffect(() => {
+ const checkLogin = async () => {
+ try {
+ if (magic) {
+ const result = await magic?.oauth.getRedirectResult();
+ //do stuff with user profile data
+ saveToken(result.magic.idToken, setToken, 'SOCIAL');
+ setLoadingFlag('false');
+ }
+ } catch (e) {
+ console.log('social login error: ' + e);
+ setLoadingFlag('false');
+ }
+ };
- checkLogin()
- }, [magic, setToken])
+ checkLogin();
+ }, [magic, setToken]);
- const login = async () => {
- setLoadingFlag('true')
- await magic?.oauth.loginWithRedirect({
- provider: 'google',
- redirectURI: window.location.origin,
- })
- }
+ const login = async () => {
+ setLoadingFlag('true');
+ await magic?.oauth.loginWithRedirect({
+ provider: 'google',
+ redirectURI: window.location.origin,
+ });
+ };
- const setLoadingFlag = (loading: string) => {
- localStorage.setItem('isAuthLoading', loading)
- setIsAuthLoading(loading)
- }
+ const setLoadingFlag = (loading: string) => {
+ localStorage.setItem('isAuthLoading', loading);
+ setIsAuthLoading(loading);
+ };
- return (
-
- Google Login
- {isAuthLoading && isAuthLoading !== 'false' ? (
-
- ) : (
-
-
0
- ? 'cursor-default'
- : 'cursor-pointer'
- )}
- onClick={() => {
- if (token.length == 0) login()
- }}>
-
-
Google
-
-
- )}
-
- )
-}
-export default Google
+ return (
+
+ Google Login
+ {isAuthLoading && isAuthLoading !== 'false' ? (
+
+ ) : (
+
+
{
+ if (token.length == 0) login();
+ }}
+ disabled={false}
+ >
+
+ Continue with Google
+
+
+ )}
+
+ );
+};
+export default Google;
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/LoginForm.tsx b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/LoginForm.tsx
deleted file mode 100644
index 80a53f2..0000000
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/LoginForm.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import {LoginProps} from '@/utils/types'
-import {useEffect, useMemo, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '../../ui/Spinner'
-import {useRouter} from 'next/router'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
-
-const setScriptAttributesAndAddScript = (src: string) => {
- const script = document.createElement('script')
- script.src = src
- script.setAttribute(
- 'data-magic-publishable-api-key',
- process.env.NEXT_PUBLIC_MAGIC_API_KEY!
- )
- script.setAttribute('data-redirect-uri', '/')
- script.async = true
-
- document.body.appendChild(script)
-}
-
-const LoginForm = ({token, setToken}: LoginProps) => {
- const router = useRouter()
- const [isLoginInProgress, setLoginInProgress] = useState(false)
-
- useMemo(async () => {
- if (token.length == 0 && router.query) {
- if (router.query.didt) {
- await saveToken(router.query.didt as string, setToken, 'FORM')
- router.replace('/', undefined, {shallow: true})
- }
- if (router.query.magic_credential) {
- await saveToken(
- router.query.magic_credential as string,
- setToken,
- 'FORM'
- )
- router.replace('/', undefined, {shallow: true})
- }
- }
- }, [router, setToken, token.length])
-
- useEffect(() => {
- if (token.length > 0 && !isLoginInProgress) {
- setLoginInProgress(false)
- }
- }, [token, setLoginInProgress, isLoginInProgress])
-
- const handleLogin = () => {
- setLoginInProgress(true)
- setScriptAttributesAndAddScript('https://auth.magic.link/pnp/login')
- }
-
- return (
-
- Login Form
- handleLogin()}>
- {isLoginInProgress ? : 'Login'}
-
-
- Please wait a few seconds after clicking login as this button is
- executing a magic script
-
-
- )
-}
-
-export default LoginForm
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/SMSOTP.tsx b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/SMSOTP.tsx
index 239e4ac..2b3e474 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/SMSOTP.tsx
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/SMSOTP.tsx
@@ -1,90 +1,84 @@
-import {useState} from 'react'
-import {useMagic} from '../MagicProvider'
-import showToast from '@/utils/showToast'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import {RPCError, RPCErrorCode} from 'magic-sdk'
-import {LoginProps} from '@/utils/types'
-import {saveToken} from '@/utils/common'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
-import FormInput from '@/components/ui/FormInput'
+import { useState } from 'react';
+import { useMagic } from '../MagicProvider';
+import showToast from '@/utils/showToast';
+import Spinner from '../../ui/Spinner';
+import { RPCError, RPCErrorCode } from 'magic-sdk';
+import { LoginProps } from '@/utils/types';
+import { saveToken } from '@/utils/common';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
+import FormInput from '@/components/ui/FormInput';
-const SMSOTP = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [phone, setPhone] = useState('')
- const [phoneError, setPhoneError] = useState(false)
- const [isLoginInProgress, setLoginInProgress] = useState(false)
+const SMSOTP = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [phone, setPhone] = useState('');
+ const [phoneError, setPhoneError] = useState(false);
+ const [isLoginInProgress, setLoginInProgress] = useState(false);
- const handleLogin = async () => {
- if (!phone.match(/^\+?\d{10,14}$/)) {
- setPhoneError(true)
- } else {
- try {
- setLoginInProgress(true)
- setPhoneError(false)
- const account = await magic?.auth.loginWithSMS({
- phoneNumber: phone,
- })
- if (account) {
- saveToken(account, setToken, 'SMS')
- setPhone('')
- }
- } catch (e) {
- console.log('login error: ' + JSON.stringify(e))
- if (e instanceof RPCError) {
- switch (e.code) {
- case RPCErrorCode.MagicLinkFailedVerification:
- case RPCErrorCode.MagicLinkExpired:
- case RPCErrorCode.MagicLinkRateLimited:
- case RPCErrorCode.UserAlreadyLoggedIn:
- showToast({message: e.message, type: 'error'})
- break
- default:
- showToast({
- message:
- 'Something went wrong. Please try again',
- type: 'error',
- })
- }
- }
- } finally {
- setLoginInProgress(false)
- }
- }
- }
+ const handleLogin = async () => {
+ if (!phone.match(/^\+?\d{10,14}$/)) {
+ setPhoneError(true);
+ } else {
+ try {
+ setLoginInProgress(true);
+ setPhoneError(false);
+ const account = await magic?.auth.loginWithSMS({
+ phoneNumber: phone,
+ });
+ if (account) {
+ saveToken(account, setToken, 'SMS');
+ setPhone('');
+ }
+ } catch (e) {
+ console.log('login error: ' + JSON.stringify(e));
+ if (e instanceof RPCError) {
+ switch (e.code) {
+ case RPCErrorCode.MagicLinkFailedVerification:
+ case RPCErrorCode.MagicLinkExpired:
+ case RPCErrorCode.MagicLinkRateLimited:
+ case RPCErrorCode.UserAlreadyLoggedIn:
+ showToast({ message: e.message, type: 'error' });
+ break;
+ default:
+ showToast({
+ message: 'Something went wrong. Please try again',
+ type: 'error',
+ });
+ }
+ }
+ } finally {
+ setLoginInProgress(false);
+ }
+ }
+ };
- return (
-
- SMS Login
-
- {
- if (phoneError) setPhoneError(false)
- setPhone(e.target.value)
- }}
- placeholder={
- token.length > 0 ? 'Already logged in' : '+11234567890'
- }
- value={phone}
- />
- {phoneError && (
-
- Enter a valid phone number
-
- )}
- 0 ? false : phone.length == 0)
- }
- onClick={() => handleLogin()}>
- {isLoginInProgress ? : 'Login'}
-
-
-
- )
-}
+ return (
+
+ SMS Login
+
+ {
+ if (phoneError) setPhoneError(false);
+ setPhone(e.target.value);
+ }}
+ placeholder={token.length > 0 ? 'Already logged in' : '+11234567890'}
+ value={phone}
+ />
+ {phoneError && (
+
+ Enter a valid phone number
+
+ )}
+ 0 ? false : phone.length == 0)}
+ onClick={() => handleLogin()}
+ >
+ {isLoginInProgress ? : 'Log in / Sign up'}
+
+
+
+ );
+};
-export default SMSOTP
+export default SMSOTP;
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Twitch.tsx b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Twitch.tsx
index 3f03e01..8986ba7 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Twitch.tsx
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Twitch.tsx
@@ -1,81 +1,73 @@
-import {LoginProps} from '@/utils/types'
-import {useMagic} from '../MagicProvider'
-import {useEffect, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import Image from 'next/image'
-import twitch from 'public/social/Twitch.svg'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
+import { LoginProps } from '@/utils/types';
+import { useMagic } from '../MagicProvider';
+import { useEffect, useState } from 'react';
+import { saveToken } from '@/utils/common';
+import Spinner from '../../ui/Spinner';
+import classNames from 'classnames';
+import Image from 'next/image';
+import twitch from 'public/social/Twitch.svg';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
-const Twitch = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [isAuthLoading, setIsAuthLoading] = useState(null)
+const Twitch = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [isAuthLoading, setIsAuthLoading] = useState(null);
- useEffect(() => {
- setIsAuthLoading(localStorage.getItem('isAuthLoading'))
- }, [])
+ useEffect(() => {
+ setIsAuthLoading(localStorage.getItem('isAuthLoading'));
+ }, []);
- useEffect(() => {
- const checkLogin = async () => {
- try {
- if (magic) {
- const result = await magic?.oauth.getRedirectResult()
- //do stuff with user profile data
- saveToken(result.magic.idToken, setToken, 'SOCIAL')
- setLoadingFlag('false')
- }
- } catch (e) {
- console.log('social login error: ' + e)
- setLoadingFlag('false')
- }
- }
+ useEffect(() => {
+ const checkLogin = async () => {
+ try {
+ if (magic) {
+ const result = await magic?.oauth.getRedirectResult();
+ //do stuff with user profile data
+ saveToken(result.magic.idToken, setToken, 'SOCIAL');
+ setLoadingFlag('false');
+ }
+ } catch (e) {
+ console.log('social login error: ' + e);
+ setLoadingFlag('false');
+ }
+ };
- checkLogin()
- }, [magic, setToken])
+ checkLogin();
+ }, [magic, setToken]);
- const login = async () => {
- setLoadingFlag('true')
- await magic?.oauth.loginWithRedirect({
- provider: 'twitch',
- redirectURI: window.location.origin,
- })
- }
+ const login = async () => {
+ setLoadingFlag('true');
+ await magic?.oauth.loginWithRedirect({
+ provider: 'twitch',
+ redirectURI: window.location.origin,
+ });
+ };
- const setLoadingFlag = (loading: string) => {
- localStorage.setItem('isAuthLoading', loading)
- setIsAuthLoading(loading)
- }
+ const setLoadingFlag = (loading: string) => {
+ localStorage.setItem('isAuthLoading', loading);
+ setIsAuthLoading(loading);
+ };
- return (
-
- Twitch Login
- {isAuthLoading && isAuthLoading !== 'false' ? (
-
- ) : (
-
-
0
- ? 'cursor-default'
- : 'cursor-pointer'
- )}
- onClick={() => {
- if (token.length == 0) login()
- }}>
-
-
Twitch
-
-
- )}
-
- )
-}
-export default Twitch
+ return (
+
+ Twitch Login
+ {isAuthLoading && isAuthLoading !== 'false' ? (
+
+ ) : (
+
+
{
+ if (token.length == 0) login();
+ }}
+ disabled={false}
+ >
+
+ Continue with Twitch
+
+
+ )}
+
+ );
+};
+export default Twitch;
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Twitter.tsx b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Twitter.tsx
index d60db9e..f90a7a2 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Twitter.tsx
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/src/components/magic/auth/Twitter.tsx
@@ -1,81 +1,73 @@
-import {LoginProps} from '@/utils/types'
-import {useMagic} from '../MagicProvider'
-import {useEffect, useState} from 'react'
-import {saveToken} from '@/utils/common'
-import Spinner from '../../ui/Spinner'
-import classNames from 'classnames'
-import Image from 'next/image'
-import twitter from 'public/social/Twitter.svg'
-import Card from '../../ui/Card'
-import CardHeader from '../../ui/CardHeader'
+import { LoginProps } from '@/utils/types';
+import { useMagic } from '../MagicProvider';
+import { useEffect, useState } from 'react';
+import { saveToken } from '@/utils/common';
+import Spinner from '../../ui/Spinner';
+import classNames from 'classnames';
+import Image from 'next/image';
+import twitter from 'public/social/Twitter.svg';
+import Card from '../../ui/Card';
+import CardHeader from '../../ui/CardHeader';
-const Twitter = ({token, setToken}: LoginProps) => {
- const {magic} = useMagic()
- const [isAuthLoading, setIsAuthLoading] = useState(null)
+const Twitter = ({ token, setToken }: LoginProps) => {
+ const { magic } = useMagic();
+ const [isAuthLoading, setIsAuthLoading] = useState(null);
- useEffect(() => {
- setIsAuthLoading(localStorage.getItem('isAuthLoading'))
- }, [])
+ useEffect(() => {
+ setIsAuthLoading(localStorage.getItem('isAuthLoading'));
+ }, []);
- useEffect(() => {
- const checkLogin = async () => {
- try {
- if (magic) {
- const result = await magic?.oauth.getRedirectResult()
- //do stuff with user profile data
- saveToken(result.magic.idToken, setToken, 'SOCIAL')
- setLoadingFlag('false')
- }
- } catch (e) {
- console.log('social login error: ' + e)
- setLoadingFlag('false')
- }
- }
+ useEffect(() => {
+ const checkLogin = async () => {
+ try {
+ if (magic) {
+ const result = await magic?.oauth.getRedirectResult();
+ //do stuff with user profile data
+ saveToken(result.magic.idToken, setToken, 'SOCIAL');
+ setLoadingFlag('false');
+ }
+ } catch (e) {
+ console.log('social login error: ' + e);
+ setLoadingFlag('false');
+ }
+ };
- checkLogin()
- }, [magic, setToken])
+ checkLogin();
+ }, [magic, setToken]);
- const login = async () => {
- setLoadingFlag('true')
- await magic?.oauth.loginWithRedirect({
- provider: 'twitter',
- redirectURI: window.location.origin,
- })
- }
+ const login = async () => {
+ setLoadingFlag('true');
+ await magic?.oauth.loginWithRedirect({
+ provider: 'twitter',
+ redirectURI: window.location.origin,
+ });
+ };
- const setLoadingFlag = (loading: string) => {
- localStorage.setItem('isAuthLoading', loading)
- setIsAuthLoading(loading)
- }
+ const setLoadingFlag = (loading: string) => {
+ localStorage.setItem('isAuthLoading', loading);
+ setIsAuthLoading(loading);
+ };
- return (
-
-
- {isAuthLoading && isAuthLoading !== 'false' ? (
-
- ) : (
-
-
0
- ? 'cursor-default'
- : 'cursor-pointer'
- )}
- onClick={() => {
- if (token.length == 0) login()
- }}>
-
-
Twitter
-
-
- )}
-
- )
-}
-export default Twitter
+ return (
+
+
+ {isAuthLoading && isAuthLoading !== 'false' ? (
+
+ ) : (
+
+
{
+ if (token.length == 0) login();
+ }}
+ disabled={false}
+ >
+
+ Continue with Twitter
+
+
+ )}
+
+ );
+};
+export default Twitter;
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/src/styles/globals.css b/scaffolds/nextjs-solana-dedicated-wallet/template/src/styles/globals.css
index 83bde73..7222af2 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/src/styles/globals.css
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/src/styles/globals.css
@@ -47,7 +47,7 @@ ul {
}
.nft-name {
- @apply text-black font-semibold;
+ @apply font-semibold text-black;
font-family: 'Inter';
}
@@ -60,7 +60,7 @@ ul {
}
.cards-container {
- @apply mt-[-250px] relative;
+ @apply relative top-[30px] md:top-[-60px] lg:top-[-60px];
}
@media only screen and (max-width: 767px) {
@@ -70,7 +70,7 @@ ul {
}
.network-dropdown {
- @apply w-fit m-auto rounded-xl;
+ @apply m-auto w-fit rounded-xl;
}
.active-network {
@@ -116,7 +116,7 @@ ul {
@apply flex flex-col items-center min-h-screen bg-gray-300;
}
.login-method-grid {
- @apply w-[100%] grid grid-cols-4 gap-5 p-4;
+ @apply max-w-[100%] grid-rows-3 gap-5 p-4 mt-8;
}
.login-method-grid-item-container {
@@ -125,7 +125,7 @@ ul {
.login-button {
@apply w-full h-12 text-white font-semibold text-base leading-6 transition-[0.1s] text-center transition-[0.1s] m-auto px-2 py-3 rounded-[300px] border-[none];
- background: #a799ff;
+ background: #8271f3;
}
.login-button:disabled {
@@ -142,7 +142,7 @@ ul {
}
.links {
- @apply flex justify-center text-white font-semibold mt-5 mb-3 mx-auto;
+ @apply flex justify-center mx-auto mt-5 text-sm mb-3 font-semibold text-white;
}
.link {
@apply transition-[0.1s] px-[30px] py-0;
@@ -163,7 +163,7 @@ ul {
@apply cursor-pointer;
}
.link-divider {
- @apply h-5 w-px;
+ @apply w-px h-5;
}
.footer-links {
@@ -221,7 +221,7 @@ ul {
@apply w-[50px] text-center flex items-center justify-center cursor-default;
}
.loading {
- @apply animate-spin cursor-default;
+ @apply cursor-default animate-spin;
}
@keyframes rotation {
@@ -234,18 +234,18 @@ ul {
}
.card {
- @apply w-[300px] flex flex-col shadow-[0px_4px_24px_rgba(49,49,49,0.1)] mt-0 mb-[27px] mx-auto px-6 py-8 rounded-2xl bg-[#ffffff];
+ @apply w-[344px] flex flex-col shadow-[0px_4px_24px_rgba(49,49,49,0.1)] mt-0 mb-[27px] mx-auto px-6 py-8 rounded-2xl bg-[#ffffff];
}
.card-header {
@apply text-xl font-semibold text-left mt-0 mb-[25px];
}
.card-label-container {
- @apply flex justify-between items-center mb-3;
+ @apply flex items-center justify-between mb-3;
}
.card-label {
- @apply text-sm font-medium cursor-pointer;
+ @apply text-sm font-medium cursor-pointer;
}
.toast {
@apply fixed w-fit text-white font-medium shadow-[4px_8px_20px_rgba(0,0,0,0.15)] mx-auto my-0 px-4 py-2 rounded-[10px] top-[30px] inset-x-0 bg-[#00875f];
@@ -291,10 +291,35 @@ a {
}
.app-header-container {
- @apply block pt-4 w-full drop-shadow-[0_35px_35px_rgba(0,0,0,0.25)] min-h-[30vh] flex flex-col items-center bg-magic block;
+ @apply block w-full drop-shadow-[0_35px_35px_rgba(0,0,0,0.25)] min-h-[40%] flex-col gap-2.5 p-8 items-center bg-[url('/login_bg.png')] bg-cover bg-no-repeat pb-20;
text-align: -webkit-center;
}
.redirect-container {
- @apply flex flex-col items-center min-h-screen bg-[length:100%_auto] bg-[url('/background.svg')];
+ @apply flex flex-col items-center h-screen bg-center bg-cover bg-no-repeat bg-[url('/redirect_bg.png')];
+}
+
+.redirect-card {
+ @apply bg-[#F8F8FA] rounded-[10px] shadow-[0px_4px_24px_rgba(49,49,49,0.1)] p-2 m-12;
+}
+
+.social-login-button {
+ @apply flex flex-row min-w-[296px] h-12 text-[#3C4043] transition-[0.1s] px-6 py-3 rounded-[300px] bg-[#ffffff] border-2 border-[#DADCE0] relative top-16;
+}
+
+.social-login-button:disabled {
+ @apply opacity-50;
+}
+
+.social-login-button:hover:enabled {
+ @apply cursor-pointer;
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #ffffff;
+}
+.social-login-button:active:enabled {
+ @apply opacity-50 scale-[0.99];
+ background: linear-gradient(0deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), #ffffff;
+}
+
+.api-button {
+ @apply bg-[#6844bc] text-[#FFFFFF] flex w-[280px] justify-center items-center h-12 font-semibold text-base leading-6 transition-[0.1s] px-6 py-3 rounded-[300px] border-[none];
}
diff --git a/scaffolds/nextjs-solana-dedicated-wallet/template/tailwind.config.js b/scaffolds/nextjs-solana-dedicated-wallet/template/tailwind.config.js
index 1da1a7e..0fc0404 100644
--- a/scaffolds/nextjs-solana-dedicated-wallet/template/tailwind.config.js
+++ b/scaffolds/nextjs-solana-dedicated-wallet/template/tailwind.config.js
@@ -1,19 +1,17 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
- content: [
- './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
- './src/components/**/*.{js,ts,jsx,tsx,mdx}',
- './src/app/**/*.{js,ts,jsx,tsx,mdx}',
- ],
- theme: {
- extend: {
- backgroundImage: {
- magic: "url('../../public//background.svg')",
- 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
- 'gradient-conic':
- 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
- },
- },
- },
- plugins: [],
-}
+ content: [
+ './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
+ './src/components/**/*.{js,ts,jsx,tsx,mdx}',
+ './src/app/**/*.{js,ts,jsx,tsx,mdx}',
+ ],
+ theme: {
+ extend: {
+ backgroundImage: {
+ 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
+ 'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
+ },
+ },
+ },
+ plugins: [],
+};
diff --git a/scaffolds/nextjs-universal-wallet/scaffold.ts b/scaffolds/nextjs-universal-wallet/scaffold.ts
index 8559db2..6d4e582 100644
--- a/scaffolds/nextjs-universal-wallet/scaffold.ts
+++ b/scaffolds/nextjs-universal-wallet/scaffold.ts
@@ -2,7 +2,6 @@ import { Flags } from 'core/flags';
import BaseScaffold from 'core/types/BaseScaffold';
import { Prompt } from 'enquirer';
import { BlockchainNetworkPrompt, PublishableApiKeyPrompt } from 'scaffolds/prompts';
-import * as fs from 'fs';
export type Data = BlockchainNetworkPrompt.Data & PublishableApiKeyPrompt.Data;
diff --git a/scaffolds/nextjs-universal-wallet/template/.env.example b/scaffolds/nextjs-universal-wallet/template/.env.example
new file mode 100644
index 0000000..4b4c3b1
--- /dev/null
+++ b/scaffolds/nextjs-universal-wallet/template/.env.example
@@ -0,0 +1,2 @@
+NEXT_PUBLIC_BLOCKCHAIN_NETWORK=<%= network %>
+NEXT_PUBLIC_MAGIC_API_KEY=<%= publishableApiKey %>
\ No newline at end of file
diff --git a/scaffolds/nextjs-universal-wallet/template/.eslintrc.json b/scaffolds/nextjs-universal-wallet/template/.eslintrc.json
new file mode 100644
index 0000000..bffb357
--- /dev/null
+++ b/scaffolds/nextjs-universal-wallet/template/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+ "extends": "next/core-web-vitals"
+}
diff --git a/scaffolds/nextjs-universal-wallet/template/.gitignore b/scaffolds/nextjs-universal-wallet/template/.gitignore
new file mode 100644
index 0000000..c98ad77
--- /dev/null
+++ b/scaffolds/nextjs-universal-wallet/template/.gitignore
@@ -0,0 +1,39 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env*.local
+.env
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
+
+#environment
+.env
\ No newline at end of file
diff --git a/scaffolds/nextjs-universal-wallet/template/README.md b/scaffolds/nextjs-universal-wallet/template/README.md
new file mode 100644
index 0000000..68281ea
--- /dev/null
+++ b/scaffolds/nextjs-universal-wallet/template/README.md
@@ -0,0 +1,44 @@
+This scaffold is meant to help you bootstrap your own projects with Magic's [Universal Wallet](https://magic.link/docs/connect/overview). Magic is a developer SDK that integrates with your application to enable passwordless Web3 onboarding.
+
+The folder structure of this scaffold is designed to encapsulate all things Magic into one place so you can easily add or remove components and functionality. For example, all Magic-specific components are in the `src/components/magic` directory while generic UI components are in the `src/components/ui` directory.
+
+## Next.js
+
+This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
+
+## Getting Started
+
+First, run the development server:
+
+```bash
+npm run dev
+# or
+yarn dev
+# or
+pnpm dev
+```
+
+Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+
+You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
+
+[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
+
+The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
+
+This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
+
+## Learn More
+
+To learn more about Next.js, take a look at the following resources:
+
+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+
+You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
+
+## Deploy on Vercel
+
+The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
+
+Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
diff --git a/scaffolds/nextjs-universal-wallet/template/next.config.js b/scaffolds/nextjs-universal-wallet/template/next.config.js
new file mode 100644
index 0000000..91ef62f
--- /dev/null
+++ b/scaffolds/nextjs-universal-wallet/template/next.config.js
@@ -0,0 +1,6 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ reactStrictMode: true,
+};
+
+module.exports = nextConfig;
diff --git a/scaffolds/nextjs-universal-wallet/template/package.json b/scaffolds/nextjs-universal-wallet/template/package.json
new file mode 100644
index 0000000..4702fc9
--- /dev/null
+++ b/scaffolds/nextjs-universal-wallet/template/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "<%= projectName %>",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
+ "lint": "next lint --fix"
+ },
+ "dependencies": {
+ "@types/node": "18.15.11",
+ "@types/react": "18.0.35",
+ "@types/react-dom": "18.0.11",
+ "eslint-config-next": "13.3.0",
+ "magic-sdk": "^16.2.0",
+ "next": "13.3.0",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "typescript": "5.0.4",
+ "web3": "^1.9.0"
+ },
+ "devDependencies": {
+ "autoprefixer": "^10.4.15",
+ "eslint": "^8.45.0",
+ "postcss": "^8.4.28",
+ "tailwindcss": "^3.3.3"
+ }
+}
diff --git a/scaffolds/nextjs-universal-wallet/template/postcss.config.js b/scaffolds/nextjs-universal-wallet/template/postcss.config.js
new file mode 100644
index 0000000..12a703d
--- /dev/null
+++ b/scaffolds/nextjs-universal-wallet/template/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/scaffolds/nextjs-universal-wallet/template/public/info.svg b/scaffolds/nextjs-universal-wallet/template/public/info.svg
new file mode 100644
index 0000000..df6edb9
--- /dev/null
+++ b/scaffolds/nextjs-universal-wallet/template/public/info.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/scaffolds/nextjs-universal-wallet/template/public/link_white.svg b/scaffolds/nextjs-universal-wallet/template/public/link_white.svg
new file mode 100644
index 0000000..c87852b
--- /dev/null
+++ b/scaffolds/nextjs-universal-wallet/template/public/link_white.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/scaffolds/nextjs-universal-wallet/template/public/login_bg.png b/scaffolds/nextjs-universal-wallet/template/public/login_bg.png
new file mode 100644
index 0000000..a4021c4
Binary files /dev/null and b/scaffolds/nextjs-universal-wallet/template/public/login_bg.png differ
diff --git a/scaffolds/nextjs-universal-wallet/template/public/logo.svg b/scaffolds/nextjs-universal-wallet/template/public/logo.svg
new file mode 100644
index 0000000..e13da68
--- /dev/null
+++ b/scaffolds/nextjs-universal-wallet/template/public/logo.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/scaffolds/nextjs-universal-wallet/template/public/redirect_bg.png b/scaffolds/nextjs-universal-wallet/template/public/redirect_bg.png
new file mode 100644
index 0000000..aa322ee
Binary files /dev/null and b/scaffolds/nextjs-universal-wallet/template/public/redirect_bg.png differ
diff --git a/scaffolds/nextjs-universal-wallet/template/src/components/magic/Links.tsx b/scaffolds/nextjs-universal-wallet/template/src/components/magic/DevLinks.tsx
similarity index 100%
rename from scaffolds/nextjs-universal-wallet/template/src/components/magic/Links.tsx
rename to scaffolds/nextjs-universal-wallet/template/src/components/magic/DevLinks.tsx
diff --git a/scaffolds/nextjs-universal-wallet/template/src/components/magic/Home.tsx b/scaffolds/nextjs-universal-wallet/template/src/components/magic/Home.tsx
index acb16e4..c36d8a1 100644
--- a/scaffolds/nextjs-universal-wallet/template/src/components/magic/Home.tsx
+++ b/scaffolds/nextjs-universal-wallet/template/src/components/magic/Home.tsx
@@ -4,7 +4,7 @@ import AppHeader from '../ui/AppHeader';
import Wallet from './cards/UserInfoCard';
import WalletMethods from './cards/WalletMethodsCard';
import SendTransaction from './cards/SendTransactionsCard';
-import Links from './Links';
+import Links from './DevLinks';
import Spacer from '../ui/Spacer';
import HomePageBackground from 'public/main.svg';
interface Props {
diff --git a/scaffolds/nextjs-universal-wallet/template/src/components/magic/Login.tsx b/scaffolds/nextjs-universal-wallet/template/src/components/magic/Login.tsx
index 07e5642..ad9f7bc 100644
--- a/scaffolds/nextjs-universal-wallet/template/src/components/magic/Login.tsx
+++ b/scaffolds/nextjs-universal-wallet/template/src/components/magic/Login.tsx
@@ -1,6 +1,6 @@
import React, { useState, useCallback } from 'react';
import AppHeader from '../ui/AppHeader';
-import Links from './Links';
+import Links from './DevLinks';
import ConnectButton from '../ui/ConnectButton';
import Spacer from '../ui/Spacer';
import LoginPageBackground from 'public/login.svg';
diff --git a/scaffolds/nextjs-universal-wallet/template/src/components/magic/MagicDashboardRedirect.tsx b/scaffolds/nextjs-universal-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
index 69f173b..2478f09 100644
--- a/scaffolds/nextjs-universal-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
+++ b/scaffolds/nextjs-universal-wallet/template/src/components/magic/MagicDashboardRedirect.tsx
@@ -1,32 +1,41 @@
import React, { useCallback } from 'react';
-import AppHeader from '../ui/AppHeader';
-import Links from './Links';
-import Spacer from '../ui/Spacer';
-import LoginPageBackground from 'public/login.svg';
+import Image from 'next/image';
+import Info from 'public/info.svg';
+import Link from 'public/link_white.svg';
+import Logo from 'public/logo.svg';
+import DevLinks from './DevLinks';
const MagicDashboardRedirect = () => {
const onClick = useCallback(() => {
- window.open('https://dashboard.magic.link', '_blank');
+ window.open('https://dashboard.magic.link/signup', '_blank');
}, []);
return (
-
-
-
-
-
- Please set your NEXT_PUBLIC_MAGIC_API_KEY
environment variable in .env
. You can get
- your Magic API key from the Magic Dashboard.
-
+
-
-
-
- Go to Dashboard
+
+
+
+
+
+ Please set your NEXT_PUBLIC_MAGIC_API_KEY
environment variable in .env
. You can
+ get your Magic API key from the Magic Dashboard.
+
+
+
+
+
+ Get API keys
+
-
+
);
};
diff --git a/scaffolds/nextjs-universal-wallet/template/src/styles/globals.css b/scaffolds/nextjs-universal-wallet/template/src/styles/globals.css
index 46e0d2f..e926d58 100644
--- a/scaffolds/nextjs-universal-wallet/template/src/styles/globals.css
+++ b/scaffolds/nextjs-universal-wallet/template/src/styles/globals.css
@@ -280,3 +280,11 @@ a {
.redirect-container {
@apply flex flex-col items-center min-h-screen bg-['100%_auto'] bg-[url('/login.svg')];
}
+
+.redirect-card {
+ @apply bg-[#F8F8FA] rounded-[10px] shadow-[0px_4px_24px_rgba(49,49,49,0.1)] p-2 m-12;
+}
+
+.api-button {
+ @apply bg-[#6844bc] text-[#FFFFFF] flex w-[280px] justify-center items-center h-12 font-semibold text-base leading-6 transition-[0.1s] px-6 py-3 rounded-[300px] border-[none];
+}
diff --git a/scaffolds/nextjs-universal-wallet/template/tailwind.config.js b/scaffolds/nextjs-universal-wallet/template/tailwind.config.js
new file mode 100644
index 0000000..84ecf21
--- /dev/null
+++ b/scaffolds/nextjs-universal-wallet/template/tailwind.config.js
@@ -0,0 +1,15 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: [
+ './app/**/*.{js,ts,jsx,tsx,mdx}',
+ './pages/**/*.{js,ts,jsx,tsx,mdx}',
+ './components/**/*.{js,ts,jsx,tsx,mdx}',
+
+ // Or if using `src` directory:
+ './src/**/*.{js,ts,jsx,tsx,mdx}',
+ ],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+};
diff --git a/scaffolds/nextjs-universal-wallet/template/tsconfig.json b/scaffolds/nextjs-universal-wallet/template/tsconfig.json
new file mode 100644
index 0000000..61c19ab
--- /dev/null
+++ b/scaffolds/nextjs-universal-wallet/template/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true,
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"]
+}