├── .env ├── .eslintrc.json ├── .gitignore ├── .prettierrc.json ├── README.md ├── abis ├── AerodromeRouter.json ├── UniswapV2Factory.json └── UniswapV2Router.json ├── app ├── [lang] │ ├── [network] │ │ ├── app.tsx │ │ ├── bridge │ │ │ └── page.tsx │ │ ├── layout.tsx │ │ ├── liquidity │ │ │ ├── [migrationId] │ │ │ │ └── page.tsx │ │ │ └── page.tsx │ │ └── migrate │ │ │ ├── [tokenId] │ │ │ └── page.tsx │ │ │ ├── new │ │ │ └── page.tsx │ │ │ └── page.tsx │ ├── app.tsx │ ├── dashboard │ │ └── page.tsx │ ├── index.tsx │ ├── layout.tsx │ └── page.tsx ├── favicon.ico ├── globals.css └── layout.tsx ├── application ├── liquidity │ ├── actions.tsx │ ├── api.ts │ ├── index.ts │ └── types.ts ├── locale │ ├── actions.tsx │ ├── index.ts │ └── types.ts ├── migration │ ├── actions.tsx │ ├── api.ts │ ├── index.ts │ └── types.ts ├── store.ts └── user │ ├── actions.tsx │ ├── api.ts │ ├── index.ts │ └── types.ts ├── components ├── announcement │ ├── index.tsx │ └── types.ts ├── button │ ├── index.tsx │ └── types.ts ├── card │ └── index.tsx ├── click-animation │ ├── index.tsx │ └── types.ts ├── container │ └── index.tsx ├── faq │ ├── index.tsx │ └── types.ts ├── file-input │ ├── index.tsx │ └── types.ts ├── file-sample │ ├── index.tsx │ └── types.ts ├── ham │ ├── index.tsx │ └── types.ts ├── index.ts ├── input │ ├── index.tsx │ └── types.ts ├── loader │ ├── index.tsx │ └── types.ts ├── modal │ ├── index.tsx │ └── types.ts ├── navigation │ ├── index.tsx │ ├── left.tsx │ ├── menu.tsx │ ├── modal │ │ ├── account.tsx │ │ ├── network.tsx │ │ ├── types.ts │ │ └── wallet.tsx │ ├── nav-action.tsx │ ├── nav-link.tsx │ ├── right.tsx │ └── types.ts ├── select │ ├── index.tsx │ └── types.ts ├── table │ ├── cta.tsx │ ├── empty.tsx │ ├── index.tsx │ ├── row.tsx │ ├── status.tsx │ ├── types.ts │ └── utils.tsx ├── testimonial │ ├── index.tsx │ └── types.ts ├── tiles │ └── index.tsx └── welcome │ ├── index.tsx │ └── types.ts ├── config ├── internationalization │ └── i18n.ts └── privy │ ├── abis │ ├── BasedERC20Factory.json │ ├── BasedERC20FactoryMain.json │ ├── OptimismMintableERC20Factory.json │ ├── Points.json │ ├── SuperERC20Factory.json │ └── XpMigrate.json │ ├── config.tsx │ └── rainbowkit.tsx ├── constants └── chains.ts ├── dictionaries ├── de.json ├── en.json ├── es.json └── fr.json ├── fonts ├── Aeonik │ ├── AeonikTRIAL-Bold.otf │ ├── AeonikTRIAL-BoldItalic.otf │ ├── AeonikTRIAL-Light.otf │ ├── AeonikTRIAL-LightItalic.otf │ ├── AeonikTRIAL-Regular.otf │ ├── AeonikTRIAL-RegularItalic.otf │ └── CoType-EULA-Trial.pdf └── Biform │ └── biform_regular.otf ├── funding.json ├── hooks ├── useConnect.tsx ├── useContract.tsx ├── useCopy.tsx ├── useDictionary.tsx ├── useLiquidity.ts ├── useRedux.ts ├── useScreenDetect.tsx ├── useSystemFunctions.tsx └── useTruncateText.ts ├── middleware.ts ├── next.config.mjs ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── assets │ └── Liquidity_Migration_Litepaper.pdf ├── favicon.png ├── icons │ ├── LayerTwoIcon.tsx │ ├── account-icon.tsx │ ├── aero-icon.svg │ ├── authorize-icon.tsx │ ├── base-primary-desktop-icon.svg │ ├── base-primary-mobile-icon.tsx │ ├── base-secondary-desktop-icon.svg │ ├── base-secondary-mobile-icon.svg │ ├── bitcoin-icon.svg │ ├── blue-check-mark-icon.svg │ ├── bridge-landing.svg │ ├── bridge-link-icon.svg │ ├── change-indicator-icon.tsx │ ├── check-icon.svg │ ├── check-small-icon.svg │ ├── close-icon.svg │ ├── copy-icon.svg │ ├── copy-secondary-icon.svg │ ├── degen-icon.svg │ ├── delete-icon.svg │ ├── disconnect-icon.svg │ ├── double-check-icon.svg │ ├── earn-icon.svg │ ├── easy-icon.svg │ ├── eth-icon.tsx │ ├── ethereum-icon.svg │ ├── exclaim-icon.svg │ ├── fast-icon.svg │ ├── flash-icon.tsx │ ├── footer-logo.svg │ ├── forward-icon.svg │ ├── git-close-icon.svg │ ├── git-merge-icon.tsx │ ├── github-button-icon.tsx │ ├── github-desktop-icon.svg │ ├── github-mobile-icon.svg │ ├── grin-icon.svg │ ├── ham-icon.svg │ ├── hero-base-bland-icon.tsx │ ├── hero-base-icon.tsx │ ├── hero-bg-lines.tsx │ ├── hero-fade-shape.tsx │ ├── hero-icon.tsx │ ├── hero-mode-icon.tsx │ ├── hero-optimism-icon.tsx │ ├── hero-scroll-icon.tsx │ ├── hero-tiles.tsx │ ├── home-icon.svg │ ├── inc-icon-sm.svg │ ├── index.ts │ ├── info-icon.svg │ ├── ink-icon.svg │ ├── left-arrow-icon.svg │ ├── linea-icon.svg │ ├── link-right-arrow.tsx │ ├── liquidity-landing-alt.svg │ ├── liquidity-landing.svg │ ├── liquidity-link-icon.tsx │ ├── loading-icon.tsx │ ├── logo-alt.svg │ ├── logo.tsx │ ├── merged-icon.svg │ ├── merged-secondary-icon.tsx │ ├── merged-tertiary-icon.svg │ ├── migrate-landing.svg │ ├── migrate-link-icon.tsx │ ├── minus-icon.tsx │ ├── mobile-migrate-landing.svg │ ├── mode-desktop-icon.svg │ ├── mode-mobile-icon.svg │ ├── mode-primary-mobile-icon.tsx │ ├── optimism-desktop-icon.svg │ ├── optimism-mobile-icon.svg │ ├── optimism-primary-mobile-icon.tsx │ ├── override.tsx │ ├── pdf-icon.svg │ ├── plus-icon.tsx │ ├── polygon-icon.svg │ ├── rays-icon.svg │ ├── right-arrow-icon.svg │ ├── right-carret-dark-icon.svg │ ├── right-carret-light-icon.svg │ ├── rounded-close-icon.svg │ ├── scroll-desktop-icon.svg │ ├── scroll-mobile-icon.svg │ ├── scroll-primary-mobile-icon.svg │ ├── search-icon.svg │ ├── secondary-close-icon.tsx │ ├── secondary-copy-icon.svg │ ├── secondary-select-icon.svg │ ├── select-icon.svg │ ├── select-secondary-icon.svg │ ├── sm-logo.svg │ ├── solana-icon.svg │ ├── success-icon.tsx │ ├── super-migrate-logo.tsx │ ├── svg-icon.svg │ ├── telegram-icon.tsx │ ├── text-sample-icon.svg │ ├── trickle-icon.tsx │ ├── uniswap-icon.tsx │ ├── upload-icon.svg │ ├── verified-icon.svg │ ├── wallet-icon.svg │ ├── web-icon.tsx │ ├── world-chain-icon.svg │ ├── x-icon.tsx │ └── zora-icon.svg ├── images │ ├── earn.svg │ ├── easy.svg │ ├── fast.svg │ ├── grin.png │ ├── gulden.png │ └── handshake.png ├── next.svg └── vercel.svg ├── tailwind.config.ts ├── tsconfig.json ├── utils ├── aerodrome.ts ├── axios.ts ├── helpers.ts ├── read-contract.ts ├── storage.ts └── uniswap.ts ├── views ├── bridge │ ├── dummy.ts │ └── index.tsx ├── dashboard │ ├── index.tsx │ ├── selection.tsx │ └── types.ts ├── home │ ├── header │ │ ├── action.tsx │ │ ├── index.tsx │ │ ├── menu.tsx │ │ └── type.ts │ ├── hero │ │ ├── index.tsx │ │ ├── lottie.json │ │ └── migratorSvg.tsx │ ├── index.tsx │ └── sections │ │ ├── SectionOne.tsx │ │ ├── SectionTwo.tsx │ │ ├── faqs │ │ ├── data.ts │ │ └── index.tsx │ │ ├── footer │ │ ├── data.ts │ │ └── index.tsx │ │ └── testimonials │ │ ├── dummy.ts │ │ ├── index.tsx │ │ └── types.ts ├── index.ts ├── liquidity │ ├── add.tsx │ ├── claim-modal.tsx │ ├── dummy.tsx │ ├── extra.tsx │ ├── index.tsx │ ├── info.tsx │ ├── input.tsx │ └── types.ts ├── migrate-liquidity │ ├── change-indicator.tsx │ ├── chart.tsx │ ├── dummy.ts │ ├── header.tsx │ ├── index.tsx │ ├── migrate-liquidity-form │ │ ├── index.tsx │ │ └── loading.tsx │ └── types.ts ├── network-migrate │ ├── connect │ │ ├── connect-modal.tsx │ │ └── index.tsx │ └── index.tsx ├── new-migrate │ ├── header.tsx │ ├── index.tsx │ └── migration-steps │ │ ├── header.tsx │ │ ├── index.tsx │ │ ├── step-1 │ │ ├── index.tsx │ │ ├── override-section.tsx │ │ ├── token-info.tsx │ │ └── types.ts │ │ ├── step-2 │ │ └── index.tsx │ │ ├── step-3 │ │ ├── index.tsx │ │ └── load-step.tsx │ │ ├── step-4 │ │ ├── index.tsx │ │ ├── left.tsx │ │ ├── right.tsx │ │ └── types.tsx │ │ └── types.ts └── token-detail │ ├── add-to-bridge.tsx │ ├── contract.tsx │ ├── fast-link.tsx │ ├── hash.tsx │ ├── index.tsx │ ├── pull-request.tsx │ └── types.ts └── yarn.lock /.env: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_PRIVY_APP_ID=clzqsbb0e01ftbfl2tj0jey3u -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env 30 | .env*.local 31 | 32 | # vercel 33 | .vercel 34 | 35 | # typescript 36 | *.tsbuildinfo 37 | next-env.d.ts 38 | 39 | yarn.lock -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true, 4 | "trailingComma": "all", 5 | "printWidth": 200, 6 | "endOfLine": "lf", 7 | "bracketSpacing": true, 8 | "bracketSameLine": true, 9 | "arrowParens": "always", 10 | "tabWidth": 2, 11 | "overrides": [ 12 | { 13 | "files": "*.json", 14 | "options": { 15 | "singleQuote": false 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 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). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | 15 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. 16 | 17 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. 18 | 19 | ## Learn More 20 | 21 | To learn more about Next.js, take a look at the following resources: 22 | 23 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 24 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 25 | 26 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 27 | 28 | ## Deploy on Vercel 29 | 30 | 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. 31 | 32 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 33 | -------------------------------------------------------------------------------- /app/[lang]/[network]/app.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { ReactNode, useEffect } from 'react'; 3 | import { motion } from 'framer-motion'; 4 | import { usePathname } from 'next/navigation'; 5 | 6 | import { Network } from '@/config/privy/config'; 7 | 8 | interface PageProps { 9 | params: { network: Network }; 10 | children: ReactNode; 11 | } 12 | 13 | const defaultGradient = 'linear-gradient(180deg, #FFF 0%, #FCFCFC 43%, #CCCCCC 100%)'; 14 | 15 | const networkBackgrounds: Record = { 16 | base: 'linear-gradient(180deg, #FFF 0%, #FCFCFC 43%, #0052FF 100%)', 17 | optimism: 'linear-gradient(180deg, #FFF 0%, #FCFCFC 43%, #FF1636 100%)', 18 | mode: 'linear-gradient(180deg, #FFF 0%, #FCFCFC 43%, #CDFF00 100%)', 19 | scroll: 'linear-gradient(180deg, #FFF 0%, #FCFCFC 43%, #F1C087 100%)', 20 | ink: 'linear-gradient(180deg, #FFF 0%, #FCFCFC 43%, #7132F5 100%)', 21 | linea: defaultGradient, 22 | zora: defaultGradient, 23 | 'world-chain': defaultGradient, 24 | degen: defaultGradient, 25 | }; 26 | 27 | const App = ({ params, children }: PageProps) => { 28 | const pathname = usePathname(); 29 | 30 | const isLiquidityRoutes = pathname.includes('liquidity'); 31 | 32 | useEffect(() => { 33 | if (isLiquidityRoutes) { 34 | document.body.classList.add('bg-peach-gradient'); 35 | } else { 36 | document.body.classList.remove('bg-peach-gradient'); 37 | } 38 | }, [isLiquidityRoutes]); 39 | 40 | return ( 41 |
42 | {children} 43 | {!isLiquidityRoutes && ( 44 | 48 | )} 49 |
50 | ); 51 | }; 52 | 53 | export default App; 54 | -------------------------------------------------------------------------------- /app/[lang]/[network]/bridge/page.tsx: -------------------------------------------------------------------------------- 1 | import { LangParamProp } from '@/config/internationalization/i18n'; 2 | import { BridgeView } from '@/views'; 3 | 4 | export default function Bridge({ params: { lang } }: { params: LangParamProp }) { 5 | return ; 6 | } 7 | -------------------------------------------------------------------------------- /app/[lang]/[network]/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Network } from '@/config/privy/config'; 2 | import App from './app'; 3 | 4 | interface RootProps { 5 | params: { network: Network }; 6 | children: React.ReactNode; 7 | } 8 | 9 | export default function RootLayout({ params, children }: Readonly) { 10 | return {children}; 11 | } 12 | -------------------------------------------------------------------------------- /app/[lang]/[network]/liquidity/[migrationId]/page.tsx: -------------------------------------------------------------------------------- 1 | import { Locale } from '@/config/internationalization/i18n'; 2 | import { Network } from '@/config/privy/config'; 3 | import { MigrateLiquidityView } from '@/views'; 4 | 5 | interface PageProps { 6 | params: { network: Network; lang: Locale; migrationId: string }; 7 | } 8 | 9 | export default function MigrateLiquidity({ params: { lang, network, migrationId } }: PageProps) { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /app/[lang]/[network]/liquidity/page.tsx: -------------------------------------------------------------------------------- 1 | import { LangParamProp, Locale } from '@/config/internationalization/i18n'; 2 | import { Network } from '@/config/privy/config'; 3 | import { LiquidityView } from '@/views'; 4 | 5 | interface PageProps { 6 | params: { network: Network; lang: Locale }; 7 | } 8 | 9 | export default function Liquidity({ params: { lang, network } }: PageProps) { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /app/[lang]/[network]/migrate/[tokenId]/page.tsx: -------------------------------------------------------------------------------- 1 | import { Network } from '@/config/privy/config'; 2 | import { TokenDetailView } from '@/views'; 3 | 4 | interface PageProps { 5 | params: { network: Network; tokenId: string }; 6 | } 7 | 8 | const TokenDetail = ({ params }: PageProps) => { 9 | return ; 10 | }; 11 | 12 | export default TokenDetail; 13 | -------------------------------------------------------------------------------- /app/[lang]/[network]/migrate/new/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { useLayoutEffect } from 'react'; 3 | import { toast } from 'react-toastify'; 4 | 5 | import { Network } from '@/config/privy/config'; 6 | import { NewMigrateView } from '@/views'; 7 | import useSystemFunctions from '@/hooks/useSystemFunctions'; 8 | 9 | interface PageProps { 10 | params: { network: Network }; 11 | } 12 | 13 | const NewMigrate = ({ params }: PageProps) => { 14 | const { navigate, userState } = useSystemFunctions(); 15 | 16 | const { loading, user } = userState; 17 | 18 | useLayoutEffect(() => { 19 | if (!loading && !user) { 20 | navigate.push(`/${params.network}/migrate`); 21 | toast.warning('Please connect to Github to continue'); 22 | } 23 | // eslint-disable-next-line react-hooks/exhaustive-deps 24 | }, [loading, user]); 25 | 26 | return ; 27 | }; 28 | 29 | export default NewMigrate; 30 | -------------------------------------------------------------------------------- /app/[lang]/[network]/migrate/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { Network } from '@/config/privy/config'; 4 | import { NetworkMigrationsView } from '@/views'; 5 | 6 | interface PageProps { 7 | params: { network: Network }; 8 | } 9 | 10 | const NetworkMigrations = ({ params }: PageProps) => { 11 | return ; 12 | }; 13 | 14 | export default NetworkMigrations; 15 | -------------------------------------------------------------------------------- /app/[lang]/app.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { ReactNode } from 'react'; 3 | import { Provider as ReduxProvider } from 'react-redux'; 4 | import { CookiesProvider } from 'react-cookie'; 5 | 6 | import { store } from '@/application/store'; 7 | import RainbowProvider from '@/config/privy/rainbowkit'; 8 | import { LangParamProp } from '@/config/internationalization/i18n'; 9 | import AppHome from '.'; 10 | import { SMTiles } from '@/components'; 11 | import { usePathname } from 'next/navigation'; 12 | import { isHomePage } from '@/components/navigation'; 13 | 14 | const App = ({ locale, children }: { locale: LangParamProp; children: ReactNode }) => { 15 | const pathname = usePathname(); 16 | const isHome = isHomePage(pathname); 17 | const isLiquidityRoutes = pathname.includes('liquidity'); 18 | const cookieOptions = { 19 | path: '/', 20 | expires: new Date(new Date().getTime() + 8 * 60 * 60 * 1000), 21 | }; 22 | 23 | return ( 24 | 25 | 26 | 27 | {children} 28 | {!isHome && !isLiquidityRoutes && ( 29 |
30 | 31 |
32 | )} 33 |
34 |
35 |
36 | ); 37 | }; 38 | 39 | export default App; 40 | -------------------------------------------------------------------------------- /app/[lang]/dashboard/page.tsx: -------------------------------------------------------------------------------- 1 | import { LangParamProp } from '@/config/internationalization/i18n'; 2 | import { DashboardView } from '@/views'; 3 | 4 | export default function Dashboard({ params: { lang } }: { params: LangParamProp }) { 5 | return ; 6 | } 7 | -------------------------------------------------------------------------------- /app/[lang]/index.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode, useEffect } from 'react'; 2 | import { ToastContainer } from 'react-toastify'; 3 | import { useCookies } from 'react-cookie'; 4 | 5 | import useLocaleActions from '@/application/locale/actions'; 6 | import { LangParamProp } from '@/config/internationalization/i18n'; 7 | import { SMNavigation } from '@/components'; 8 | import { setTokenHeader } from '@/utils/axios'; 9 | import useUserActions from '@/application/user/actions'; 10 | 11 | import 'react-toastify/dist/ReactToastify.css'; 12 | import { useConnect } from 'wagmi'; 13 | 14 | const AppHome = ({ locale, children }: { locale: LangParamProp; children: ReactNode }) => { 15 | const {} = useConnect(); 16 | 17 | const [cookies] = useCookies(['authtoken']); 18 | const { getLocale } = useLocaleActions(); 19 | const { getUser } = useUserActions(); 20 | 21 | const fetchUser = async () => { 22 | await setTokenHeader(cookies?.authtoken); 23 | getUser(); 24 | }; 25 | 26 | useEffect(() => { 27 | if (!cookies?.authtoken) return; 28 | 29 | fetchUser(); 30 | // eslint-disable-next-line react-hooks/exhaustive-deps 31 | }, [cookies]); 32 | 33 | useEffect(() => { 34 | getLocale({ lang: locale.lang }); 35 | // eslint-disable-next-line react-hooks/exhaustive-deps 36 | }, []); 37 | return ( 38 |
39 | 40 | {children} 41 | 42 |
43 | ); 44 | }; 45 | 46 | export default AppHome; 47 | -------------------------------------------------------------------------------- /app/[lang]/layout.tsx: -------------------------------------------------------------------------------- 1 | import { LangParamProp } from '@/config/internationalization/i18n'; 2 | import App from './app'; 3 | 4 | interface RootProps { 5 | params: LangParamProp; 6 | children: React.ReactNode; 7 | } 8 | 9 | export default function RootLayout({ params, children }: Readonly) { 10 | return {children}; 11 | } 12 | -------------------------------------------------------------------------------- /app/[lang]/page.tsx: -------------------------------------------------------------------------------- 1 | import { LangParamProp } from '@/config/internationalization/i18n'; 2 | import { HomeView } from '@/views'; 3 | 4 | export default function Home({ params: { lang } }: { params: LangParamProp }) { 5 | return ; 6 | } 7 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metastable-labs/supermigrate-interface/c70e75d74f87f622527ca65cfc99e9b73d6c8d89/app/favicon.ico -------------------------------------------------------------------------------- /app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @font-face { 6 | font-family: 'Bitform'; 7 | src: url('../fonts/Biform/biform_regular.otf'); 8 | font-weight: 400; 9 | font-style: normal; 10 | } 11 | 12 | @font-face { 13 | font-family: 'Aeonik'; 14 | src: url('../fonts/Aeonik/AeonikTRIAL-Regular.otf'); 15 | font-weight: 400; 16 | font-style: normal; 17 | } 18 | 19 | body { 20 | margin: 0; 21 | padding: 0; 22 | font-family: 'Roboto', sans-serif; 23 | background-color: #f9f9f9; 24 | } 25 | 26 | .scroll-hero-text { 27 | -webkit-text-stroke: 1px#1a1d01; 28 | } 29 | 30 | .mode-hero-text { 31 | -webkit-text-stroke: 1px #1a1d01; 32 | } 33 | 34 | .wide-full { 35 | width: calc(100% + 2px); 36 | } 37 | 38 | html { 39 | scroll-behavior: smooth; 40 | } 41 | -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import './globals.css'; 2 | import type { Metadata } from 'next'; 3 | import Script from 'next/script'; 4 | import { LangParamProp } from '@/config/internationalization/i18n'; 5 | import App from './[lang]/app'; 6 | 7 | interface RootProps { 8 | params: LangParamProp; 9 | children: React.ReactNode; 10 | } 11 | 12 | export const metadata: Metadata = { 13 | title: 'Supermigrate', 14 | description: 'Your gateway to L2s', 15 | keywords: ['base', 'migrate', 'Migration', 'Layer 2', 'Layer 1', 'Ethereum', 'base migrate', 'erc20 token to base network', 'migrate erc20 tokens', 'onchain', 'superchain', 'supermigrate'], 16 | applicationName: 'Supermigrate', 17 | openGraph: { 18 | title: 'Supermigrate', 19 | description: 'Your gateway to L2s', 20 | url: 'https://supermigrate.xyz', 21 | type: 'website', 22 | images: [ 23 | { 24 | url: 'https://res.cloudinary.com/djzeufu4j/image/upload/v1715019214/favicon_ihu7jb.png', 25 | width: 1200, 26 | height: 630, 27 | }, 28 | ], 29 | siteName: 'supermigrate.xyz', 30 | }, 31 | twitter: { 32 | card: 'summary_large_image', 33 | site: 'https://supermigrate.xyz', 34 | title: 'Supermigrate', 35 | description: 'Your gateway to L2s', 36 | images: [ 37 | { 38 | url: 'https://res.cloudinary.com/djzeufu4j/image/upload/v1715019214/favicon_ihu7jb.png', 39 | width: 1200, 40 | height: 630, 41 | }, 42 | ], 43 | }, 44 | }; 45 | 46 | export default function RootLayout({ params, children }: Readonly) { 47 | return ( 48 | 49 | 50 | {/** Google Analytics */} 51 | 61 | {children} 62 | 63 | 64 | ); 65 | } 66 | -------------------------------------------------------------------------------- /application/liquidity/actions.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import useSystemFunctions from '@/hooks/useSystemFunctions'; 4 | import api from './api'; 5 | import { CallbackProps } from '../store'; 6 | import { setLiquidities, setLiquidity, setLoading } from '.'; 7 | import { Liquidity } from './types'; 8 | 9 | const useLiquidityActions = () => { 10 | const { dispatch } = useSystemFunctions(); 11 | 12 | const getLiquidities = async () => { 13 | try { 14 | dispatch(setLoading(true)); 15 | const liqudities = await api.fetchLiquidities(); 16 | 17 | return dispatch(setLiquidities(liqudities)); 18 | } catch (error: any) { 19 | } finally { 20 | dispatch(setLoading(false)); 21 | } 22 | }; 23 | 24 | const getLiquidity = async (id: string) => { 25 | try { 26 | dispatch(setLoading(true)); 27 | const migration = await api.fetchLiquidity(id); 28 | 29 | return dispatch(setLiquidity(migration)); 30 | } catch (error: any) { 31 | } finally { 32 | dispatch(setLoading(false)); 33 | } 34 | }; 35 | 36 | const getLiquidityObject = async (body: Liquidity) => { 37 | try { 38 | return dispatch(setLiquidity(body)); 39 | } catch (error: any) {} 40 | }; 41 | 42 | const postLiquidity = async (data: any, callback?: CallbackProps) => { 43 | try { 44 | dispatch(setLoading(true)); 45 | 46 | const response = await api.postLiquidity(data); 47 | 48 | callback?.onSuccess?.(); 49 | } catch (error: any) { 50 | dispatch(setLoading(false)); 51 | } 52 | }; 53 | 54 | return { 55 | getLiquidities, 56 | getLiquidity, 57 | getLiquidityObject, 58 | postLiquidity, 59 | }; 60 | }; 61 | 62 | export default useLiquidityActions; 63 | -------------------------------------------------------------------------------- /application/liquidity/api.ts: -------------------------------------------------------------------------------- 1 | import { axiosInstance } from '@/utils/axios'; 2 | import { Liquidity } from './types'; 3 | 4 | type ILiquidity = { 5 | fetchLiquidities: () => Promise; 6 | fetchLiquidity: (id: string) => Promise; 7 | postLiquidity: (data: FormData) => Promise; 8 | }; 9 | 10 | const migration: ILiquidity = { 11 | fetchLiquidities: async (): Promise => { 12 | const response = await axiosInstance.get(`liquidities`); 13 | 14 | return response.data?.data; 15 | }, 16 | 17 | fetchLiquidity: async (id: string): Promise => { 18 | const response = await axiosInstance.get(`liquidities/${id}`); 19 | 20 | return response.data?.data; 21 | }, 22 | 23 | postLiquidity: async (data: FormData): Promise => { 24 | const response = await axiosInstance.post(`liquidities`, data); 25 | 26 | return response.data?.data; 27 | }, 28 | }; 29 | 30 | export default migration; 31 | -------------------------------------------------------------------------------- /application/liquidity/index.ts: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { createSlice } from '@reduxjs/toolkit'; 3 | import type { PayloadAction } from '@reduxjs/toolkit'; 4 | 5 | import { Liquidity } from './types'; 6 | 7 | export interface LiquidityState { 8 | liquidities: Liquidity[]; 9 | liquidity: Liquidity | undefined; 10 | loading: boolean; 11 | loadingLiquidity: boolean; 12 | } 13 | 14 | const initialState: LiquidityState = { 15 | liquidities: [], 16 | liquidity: undefined, 17 | loading: false, 18 | loadingLiquidity: false, 19 | }; 20 | 21 | export const liquidityReducer = createSlice({ 22 | name: 'liquidity', 23 | initialState, 24 | reducers: { 25 | setLoading: (state, action: PayloadAction) => { 26 | state.loading = action.payload; 27 | }, 28 | 29 | setLoadingLiquidity: (state, action: PayloadAction) => { 30 | state.loadingLiquidity = action.payload; 31 | }, 32 | 33 | setLiquidities: (state, action: PayloadAction) => { 34 | state.liquidities = [...state.liquidities, ...action.payload]; 35 | }, 36 | 37 | setLiquidity: (state, action: PayloadAction) => { 38 | state.liquidity = { ...state.liquidity, ...action.payload }; 39 | }, 40 | }, 41 | }); 42 | 43 | export const { setLoading, setLiquidities, setLiquidity, setLoadingLiquidity } = liquidityReducer.actions; 44 | 45 | export default liquidityReducer.reducer; 46 | -------------------------------------------------------------------------------- /application/liquidity/types.ts: -------------------------------------------------------------------------------- 1 | type Liquidity = { 2 | id: string; 3 | pool_token_a_address: string; 4 | pool_token_b_address: string; 5 | pool_token_a_amount: string; 6 | pool_token_b_amount: string; 7 | pool_token_amount: string; 8 | pool_token_address: string; 9 | transaction_hash: string; 10 | deployer_address: string; 11 | chain: { 12 | id: number; 13 | name: string; 14 | }; 15 | provider: string; 16 | user_id: string; 17 | created_at: string; 18 | updated_at: string; 19 | }; 20 | 21 | export type { Liquidity }; 22 | -------------------------------------------------------------------------------- /application/locale/actions.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import useSystemFunctions from '@/hooks/useSystemFunctions'; 4 | import useDictionary from '@/hooks/useDictionary'; 5 | import { LangParamProp } from '@/config/internationalization/i18n'; 6 | import { setLocale } from '.'; 7 | 8 | const useLocaleActions = () => { 9 | const { dispatch } = useSystemFunctions(); 10 | const getDictionary = useDictionary(); 11 | 12 | const getLocale = async ({ lang }: LangParamProp) => { 13 | try { 14 | const dictionary = await getDictionary(lang); 15 | 16 | return dispatch(setLocale(dictionary)); 17 | } catch (error: any) { 18 | // 19 | } 20 | }; 21 | 22 | return { 23 | getLocale, 24 | }; 25 | }; 26 | 27 | export default useLocaleActions; 28 | -------------------------------------------------------------------------------- /application/locale/index.ts: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { createSlice } from '@reduxjs/toolkit'; 3 | import type { PayloadAction } from '@reduxjs/toolkit'; 4 | import englishJson from '../../dictionaries/en.json'; 5 | 6 | import { Lang } from './types'; 7 | 8 | export interface LocaleState { 9 | locale: Lang; 10 | } 11 | 12 | const initialState: LocaleState = { 13 | locale: englishJson, 14 | }; 15 | 16 | export const userReducer = createSlice({ 17 | name: 'locale', 18 | initialState, 19 | reducers: { 20 | setLocale: (state, action: PayloadAction) => { 21 | state.locale = { ...state.locale, ...action.payload }; 22 | }, 23 | }, 24 | }); 25 | 26 | export const { setLocale } = userReducer.actions; 27 | 28 | export default userReducer.reducer; 29 | -------------------------------------------------------------------------------- /application/migration/api.ts: -------------------------------------------------------------------------------- 1 | import { axiosInstance } from '@/utils/axios'; 2 | import { Migration } from './types'; 3 | 4 | type IMigration = { 5 | fetchMigrations: () => Promise; 6 | fetchMigration: (id: string) => Promise; 7 | migrateToken: (data: FormData) => Promise; 8 | addToBridge: (id: string, data: FormData) => Promise; 9 | }; 10 | 11 | const migration: IMigration = { 12 | fetchMigrations: async (): Promise => { 13 | const response = await axiosInstance.get(`migrations`); 14 | 15 | return response.data?.data; 16 | }, 17 | 18 | fetchMigration: async (id: string): Promise => { 19 | const response = await axiosInstance.get(`migrations/${id}`); 20 | 21 | return response.data?.data; 22 | }, 23 | 24 | migrateToken: async (data: FormData): Promise => { 25 | const response = await axiosInstance.post(`migrations`, data); 26 | 27 | return response.data?.data; 28 | }, 29 | 30 | addToBridge: async (id: string, data: FormData): Promise => { 31 | const response = await axiosInstance.post(`migrations/${id}/superbridge`, data); 32 | 33 | return response.data?.data; 34 | }, 35 | }; 36 | 37 | export default migration; 38 | -------------------------------------------------------------------------------- /application/migration/index.ts: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { createSlice } from '@reduxjs/toolkit'; 3 | import type { PayloadAction } from '@reduxjs/toolkit'; 4 | 5 | import { Migration } from './types'; 6 | import { set } from 'react-hook-form'; 7 | 8 | export interface MigrationState { 9 | migrations: Migration[]; 10 | migration: Migration | undefined; 11 | loading: boolean; 12 | loadingMigration: boolean; 13 | addToBridgeLoading: boolean; 14 | } 15 | 16 | const initialState: MigrationState = { 17 | migrations: [], 18 | migration: undefined, 19 | loading: false, 20 | loadingMigration: false, 21 | addToBridgeLoading: false, 22 | }; 23 | 24 | export const migrationReducer = createSlice({ 25 | name: 'migration', 26 | initialState, 27 | reducers: { 28 | setLoading: (state, action: PayloadAction) => { 29 | state.loading = action.payload; 30 | }, 31 | 32 | setLoadingMigration: (state, action: PayloadAction) => { 33 | state.loadingMigration = action.payload; 34 | }, 35 | 36 | setMigrations: (state, action: PayloadAction) => { 37 | state.migrations = [...action.payload]; 38 | }, 39 | 40 | setMigration: (state, action: PayloadAction) => { 41 | if (action.payload) { 42 | state.migration = { ...action.payload }; 43 | } else { 44 | state.migration = undefined; 45 | } 46 | }, 47 | 48 | setAddToBridgeLoading: (state, action: PayloadAction) => { 49 | state.addToBridgeLoading = action.payload; 50 | }, 51 | }, 52 | }); 53 | 54 | export const { setLoading, setMigrations, setMigration, setLoadingMigration, setAddToBridgeLoading } = migrationReducer.actions; 55 | 56 | export default migrationReducer.reducer; 57 | -------------------------------------------------------------------------------- /application/migration/types.ts: -------------------------------------------------------------------------------- 1 | type Chain = { 2 | id: number; 3 | name: string; 4 | token_address: string; 5 | token_detail_override?: { 6 | name: string; 7 | symbol: string; 8 | decimals: number; 9 | }; 10 | transaction_hash: string; 11 | }; 12 | 13 | type PullRequest = { 14 | id: number; 15 | url: string; 16 | status: string; 17 | chain: string; 18 | installation_id: number; 19 | owner: string; 20 | }; 21 | 22 | type Migration = { 23 | id: string; 24 | name: string; 25 | symbol: string; 26 | decimals: number; 27 | logo_url: string; 28 | description: string; 29 | website: string; 30 | twitter: string; 31 | chains: Chain[]; 32 | pull_requests: PullRequest[]; 33 | status: string; 34 | user_id: string; 35 | created_at: string; 36 | updated_at: string; 37 | }; 38 | 39 | export type { Migration, Chain, PullRequest }; 40 | -------------------------------------------------------------------------------- /application/store.ts: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { configureStore } from '@reduxjs/toolkit'; 3 | 4 | import userReducer from './user'; 5 | import localeReducer from './locale'; 6 | import migrationReducer from './migration'; 7 | import liquidityReducer from './liquidity'; 8 | 9 | export interface CallbackProps { 10 | onSuccess?: Function; 11 | onError?: Function; 12 | } 13 | 14 | export const store = configureStore({ 15 | reducer: { 16 | user: userReducer, 17 | locale: localeReducer, 18 | migration: migrationReducer, 19 | liquidity: liquidityReducer, 20 | }, 21 | }); 22 | 23 | // Infer the `RootState` and `AppDispatch` types from the store itself 24 | export type RootState = ReturnType; 25 | // Inferred type: {user: UserState} 26 | export type AppDispatch = typeof store.dispatch; 27 | -------------------------------------------------------------------------------- /application/user/api.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | import { axiosInstance } from '@/utils/axios'; 4 | import { GithubAuthResponse, User } from './types'; 5 | 6 | type Response = { 7 | token: string; 8 | expire: number; 9 | user: { 10 | id: string; 11 | auth_id: string; 12 | auth_type: string; 13 | wallet_address: string; 14 | referral_code: string; 15 | is_active: boolean; 16 | created_at: string; 17 | updated_at: string; 18 | }; 19 | }; 20 | 21 | type IUser = { 22 | fetchUser: () => Promise; 23 | githubAuth: (code: string) => Promise; 24 | login: (token: string) => Promise; 25 | }; 26 | 27 | const user: IUser = { 28 | fetchUser: async (): Promise => { 29 | const response = await axiosInstance.get(`shared/auth/session`); 30 | 31 | return response.data?.data; 32 | }, 33 | 34 | githubAuth: async (code: string): Promise => { 35 | const response = await axiosInstance.post(`shared/auth/github`, { code }); 36 | 37 | return response.data?.data; 38 | }, 39 | 40 | login: async (token: string): Promise => { 41 | const response = await axios.post( 42 | `https://api.supermigrate.xyz/v1/shared/auth`, 43 | {}, 44 | { 45 | headers: { 46 | Authorization: `Bearer ${token}`, 47 | }, 48 | }, 49 | ); 50 | 51 | return response.data?.data; 52 | }, 53 | }; 54 | 55 | export default user; 56 | -------------------------------------------------------------------------------- /application/user/index.ts: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { createSlice } from '@reduxjs/toolkit'; 3 | import type { PayloadAction } from '@reduxjs/toolkit'; 4 | 5 | import { User } from './types'; 6 | 7 | export interface UserState { 8 | user: User | undefined; 9 | loading: boolean; 10 | } 11 | 12 | const initialState: UserState = { 13 | user: undefined, 14 | loading: false, 15 | }; 16 | 17 | export const userReducer = createSlice({ 18 | name: 'user', 19 | initialState, 20 | reducers: { 21 | setLoading: (state, action: PayloadAction) => { 22 | state.loading = action.payload; 23 | }, 24 | 25 | setUser: (state, action: PayloadAction) => { 26 | if (action.payload) { 27 | state.user = { ...action.payload }; 28 | } else { 29 | state.user = undefined; 30 | } 31 | }, 32 | }, 33 | }); 34 | 35 | export const { setLoading, setUser } = userReducer.actions; 36 | 37 | export default userReducer.reducer; 38 | -------------------------------------------------------------------------------- /application/user/types.ts: -------------------------------------------------------------------------------- 1 | import { Address } from 'viem'; 2 | 3 | type User = { 4 | id: string; 5 | github_id: number; 6 | auth_id: string; 7 | auth_type: string; 8 | wallet_address: string; 9 | name: string; 10 | avatar_url: string; 11 | ip_address: string; 12 | referral_code: string; 13 | is_active: boolean; 14 | created_at: string; 15 | updated_at: string; 16 | wallet: { 17 | id: string; 18 | wallet_address: Address; 19 | total_balance: number; 20 | pending_balance: number; 21 | is_active: boolean; 22 | user_id: string; 23 | created_at: string; 24 | updated_at: string; 25 | }; 26 | }; 27 | 28 | type GithubAuthResponse = { 29 | token: string; 30 | expire: number; 31 | user: User; 32 | }; 33 | 34 | export type { User, GithubAuthResponse }; 35 | -------------------------------------------------------------------------------- /components/announcement/index.tsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames'; 2 | import { AnimatePresence, motion } from 'framer-motion'; 3 | 4 | const SMAnnouncement = ({ comment, link, linkText, show, variant = 'bottom' }: ISMAnnouncement) => ( 5 | 6 | {show && ( 7 | 12 |

13 | {comment}{' '} 14 | 15 | {linkText} 16 | 17 |

18 |
19 | )} 20 |
21 | ); 22 | 23 | export default SMAnnouncement; 24 | -------------------------------------------------------------------------------- /components/announcement/types.ts: -------------------------------------------------------------------------------- 1 | interface ISMAnnouncement { 2 | comment: string; 3 | link?: string; 4 | linkText?: string; 5 | show?: boolean; 6 | variant?: 'top' | 'bottom'; 7 | } 8 | -------------------------------------------------------------------------------- /components/button/index.tsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames'; 2 | import { motion } from 'framer-motion'; 3 | 4 | import { IButton } from './types'; 5 | import { GithubButtonIcon, PlusIcon } from '@/public/icons'; 6 | import SMLoader from '../loader'; 7 | 8 | const SMButton = ({ network, onClick, text, variant = 'git', fullWidth, disabled, type = 'button', loading }: IButton) => { 9 | let iconColor; 10 | if (network === 'base' || network === 'optimism' || variant === 'bland-new') { 11 | iconColor = 'white'; 12 | } 13 | if (network === 'mode' || network === 'scroll' || network?.includes('ink')) { 14 | iconColor = '#242D01'; 15 | } 16 | 17 | return ( 18 | 38 | {!loading && variant === 'git' && } 39 | {!loading && (variant === 'new' || variant === 'bland-new') && } 40 | 41 |
48 | {loading ? : text} 49 |
50 |
51 | ); 52 | }; 53 | 54 | export default SMButton; 55 | -------------------------------------------------------------------------------- /components/button/types.ts: -------------------------------------------------------------------------------- 1 | import { Network } from '@/config/privy/config'; 2 | 3 | type ButtonVariants = 'git' | 'new' | 'bland-new' | 'plain' | 'tertiary'; 4 | 5 | interface IButton { 6 | variant?: ButtonVariants; 7 | onClick?: () => void; 8 | text: string; 9 | network?: Network; 10 | fullWidth?: boolean; 11 | disabled?: boolean; 12 | type?: 'button' | 'submit' | 'reset'; 13 | loading?: boolean; 14 | } 15 | 16 | export type { IButton, ButtonVariants }; 17 | -------------------------------------------------------------------------------- /components/click-animation/index.tsx: -------------------------------------------------------------------------------- 1 | import { motion } from 'framer-motion'; 2 | import { ClickAnimation } from './types'; 3 | 4 | const SMClickAnimation = ({ children, onClick, className }: ClickAnimation) => { 5 | return ( 6 | 7 | {children} 8 | 9 | ); 10 | }; 11 | 12 | export default SMClickAnimation; 13 | -------------------------------------------------------------------------------- /components/click-animation/types.ts: -------------------------------------------------------------------------------- 1 | export interface ClickAnimation { 2 | children: React.ReactNode; 3 | onClick?: () => void; 4 | className?: string; 5 | } 6 | -------------------------------------------------------------------------------- /components/container/index.tsx: -------------------------------------------------------------------------------- 1 | const SMContainer = ({ children }: { children: React.ReactNode }) => { 2 | return
{children}
; 3 | }; 4 | 5 | export default SMContainer; 6 | -------------------------------------------------------------------------------- /components/faq/index.tsx: -------------------------------------------------------------------------------- 1 | import { AnimatePresence, motion } from 'framer-motion'; 2 | import { PlusIcon, MinusIcon } from '@/public/icons'; 3 | import classNames from 'classnames'; 4 | 5 | const SMFAQ = ({ answer, question, current, onClick }: ISMFAQ) => { 6 | return ( 7 |
8 |
9 |

{question}

10 | 11 | 12 | {current ? ( 13 | 14 | 15 | 16 | ) : ( 17 | 18 | 19 | 20 | )} 21 | 22 |
23 | 24 | 25 | 26 | {current && ( 27 | 28 | {answer} 29 | 30 | )} 31 | 32 | 33 |
34 | ); 35 | }; 36 | 37 | export default SMFAQ; 38 | -------------------------------------------------------------------------------- /components/faq/types.ts: -------------------------------------------------------------------------------- 1 | interface ISMFAQ { 2 | question: string; 3 | answer: string; 4 | current: boolean; 5 | onClick: () => void; 6 | } 7 | -------------------------------------------------------------------------------- /components/file-input/types.ts: -------------------------------------------------------------------------------- 1 | import { Network } from '@/config/privy/config'; 2 | 3 | interface ISMFileInput { 4 | name: string; 5 | disabled?: boolean; 6 | className?: string; 7 | label?: string; 8 | isRequired?: boolean; 9 | handleFileChange: any; 10 | network?: Network; 11 | show?: boolean; 12 | } 13 | 14 | export type { ISMFileInput }; 15 | -------------------------------------------------------------------------------- /components/file-sample/index.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { AnimatePresence, motion } from 'framer-motion'; 3 | 4 | import useSystemFunctions from '@/hooks/useSystemFunctions'; 5 | import { DeleteIcon, CheckSmallIcon, SVGIcon } from '@/public/icons'; 6 | 7 | const formatFileSize = (bytes: number, decimals = 2) => { 8 | if (bytes === 0) return '0 Bytes'; 9 | const k = 1024; 10 | const dm = decimals < 0 ? 0 : decimals; 11 | const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; 12 | const i = Math.floor(Math.log(bytes) / Math.log(k)); 13 | return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]; 14 | }; 15 | 16 | const SMFileSample = ({ file, deleteFile }: ISMFileSmaple) => { 17 | const { locale } = useSystemFunctions(); 18 | const { completed } = locale.components.fileInput; 19 | const fileSize = file ? formatFileSize(file.size) : ''; 20 | 21 | return ( 22 | 23 | {file && ( 24 | 30 |
31 | 32 |
33 | {file.name} 34 |
35 | 36 | {fileSize} of {fileSize} 37 | 38 | 39 | 40 | 41 | 42 | 43 | {completed} 44 |
45 |
46 |
47 | 48 |
49 | 50 |
51 |
52 | )} 53 |
54 | ); 55 | }; 56 | 57 | export default SMFileSample; 58 | -------------------------------------------------------------------------------- /components/file-sample/types.ts: -------------------------------------------------------------------------------- 1 | interface ISMFileSmaple { 2 | file: File | null | undefined; 3 | deleteFile: () => void; 4 | } 5 | -------------------------------------------------------------------------------- /components/ham/index.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { CloseIcon, HamIcon } from '@/public/icons'; 3 | 4 | import { AnimatePresence, motion } from 'framer-motion'; 5 | 6 | const SMHam = ({ isOpen, onClick }: ISMHam) => { 7 | return ( 8 |
9 | 10 | {isOpen ? ( 11 | 12 | 13 | 14 | ) : ( 15 | 16 | 17 | 18 | )} 19 | 20 |
21 | ); 22 | }; 23 | 24 | export default SMHam; 25 | -------------------------------------------------------------------------------- /components/ham/types.ts: -------------------------------------------------------------------------------- 1 | interface ISMHam { 2 | isOpen: boolean; 3 | onClick: () => void; 4 | } 5 | -------------------------------------------------------------------------------- /components/index.ts: -------------------------------------------------------------------------------- 1 | import SMContainer from './container'; 2 | import SMNavigation from './navigation'; 3 | import SMClickAnimation from './click-animation'; 4 | import SMModal from './modal'; 5 | import SMTable from './table'; 6 | import SMButton from './button'; 7 | import SMInput from './input'; 8 | import SMFileInput from './file-input'; 9 | import SMTestimonial from './testimonial'; 10 | import SMFAQ from './faq'; 11 | import SMSelect from './select'; 12 | import SMLoader from './loader'; 13 | import SMWelcome from './welcome'; 14 | import SMTiles from './tiles'; 15 | import SMAnnouncement from './announcement'; 16 | import SMFileSample from './file-sample'; 17 | 18 | export { SMContainer, SMClickAnimation, SMNavigation, SMModal, SMTable, SMButton, SMInput, SMFileInput, SMTestimonial, SMFAQ, SMSelect, SMLoader, SMWelcome, SMTiles, SMAnnouncement, SMFileSample }; 19 | -------------------------------------------------------------------------------- /components/input/index.tsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames'; 2 | 3 | import { ISMInput } from './types'; 4 | import useSystemFunctions from '@/hooks/useSystemFunctions'; 5 | 6 | const SMInput = ({ name, className, disabled, error, isRequired, label, placeholder, register, rows = 3, type, variant = 'primary' }: ISMInput) => { 7 | const { locale } = useSystemFunctions(); 8 | const { required } = locale.components.input; 9 | return ( 10 |
11 | 19 | 20 | {variant === 'primary' && ( 21 | 31 | )} 32 | 33 | {variant === 'secondary' && ( 34 |