Skip to content

Commit

Permalink
🔄 synced file(s) with circlefin/pw-sample-app-internal (#12)
Browse files Browse the repository at this point in the history
synced local file(s) with
[circlefin/pw-sample-app-internal](https://github.com/circlefin/pw-sample-app-internal).



<details>
<summary>Changed files</summary>
<ul>
<li>synced local directory <code>app/</code> with remote directory
<code>app/</code></li><li>synced local directory <code>public/</code>
with remote directory <code>public/</code></li>
</ul>
</details>

---

This PR was created automatically by the
[repo-file-sync-action](https://github.com/BetaHuhn/repo-file-sync-action)
workflow run
[#9229471376](https://github.com/circlefin/pw-sample-app-internal/actions/runs/9229471376)
  • Loading branch information
circle-github-action-bot authored May 29, 2024
1 parent 87cb543 commit 4a27424
Show file tree
Hide file tree
Showing 12 changed files with 330 additions and 116 deletions.
186 changes: 101 additions & 85 deletions app/(pages)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.

"use client";
import "../globals.css";

import createCache from "@emotion/cache";
import { QueryClient, QueryClientProvider } from "react-query";
import { W3sProvider } from "../components/Providers/W3sProvider";
import { SessionProvider } from "next-auth/react";
import Image from "next/image";
import { CacheProvider } from "@emotion/react";
import { CssVarsProvider, CssBaseline } from "@mui/joy";
import { useServerInsertedHTML } from "next/navigation";
import React from "react";
import { Inter } from "next/font/google";
import { Metadata } from "next";

import { ClientProviders, Footer } from "@/app/components";
import { Button, Typography } from "@mui/joy";
import { BookOpenIcon } from "@heroicons/react/16/solid";

const inter = Inter({
subsets: ["cyrillic"],
Expand All @@ -37,93 +34,112 @@ export default function RootLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
const queryClient = new QueryClient();

return (
<html lang='en'>
<body className={inter.className}>
<div id='__next'>
<SessionProvider>
<QueryClientProvider client={queryClient}>
<W3sProvider>
<ThemeRegistry options={{ key: "joy" }}>
<div className='flex justify-center items-center h-screen px-4'>
<div className='max-w-xl w-full h-full max-h-[660px] border border-solid border-gray-200 rounded-lg shadow-lg flex flex-col relative overflow-hidden'>
<span className='bg-secondary text-white p-3 font-medium flex items-center gap-x-2.5'>
<ClientProviders>
<div className='gradient-background'>
<div className='mx-auto max-w-7xl background-gradient h-screen flex flex-col lg:flex-row lg:gap-x-8 lg:items-start items-center lg:justify-between justify-center lg:px-8 lg:py-12'>
{/* Larger Screen Logo */}
<div className='lg:block hidden w-64'>
<Image
src={`/CircleLogoWithName.svg`}
className='mr-4'
alt='Circle Logo'
width={140}
height={36}
/>
<Typography level='title-lg' className='mt-1'>
User-Controlled Wallets
</Typography>
</div>
<AppContainer>{children}</AppContainer>
{/* Larger Screen Source Code/Docs */}
<div className='lg:flex hidden w-64 gap-x-2'>
<a
href='https://github.com/circlefin/w3s-sample-user-controlled-client-web'
target='_blank'
>
<Button
variant='outlined'
startDecorator={
<Image
src={`/CircleLogo.svg`}
alt='Circle Logo'
width={20}
height={20}
/>{" "}
Your app here
</span>
{children}
</div>
</div>
</ThemeRegistry>
</W3sProvider>
</QueryClientProvider>
</SessionProvider>
src={"/Github.svg"}
height={16}
width={16}
alt='github'
/>
}
>
Github
</Button>
</a>
<a
href='https://developers.circle.com/w3s/docs/sample-applications'
target='_blank'
>
<Button
variant='outlined'
startDecorator={<BookOpenIcon width={16} />}
>
Docs
</Button>
</a>
</div>
</div>
<Footer />
</div>
</ClientProviders>
</div>
</body>
</html>
);
}

// copied from joy-ui docs.
// https://mui.com/joy-ui/integrations/next-js-app-router/#using-joy-ui-with-the-app-router

function ThemeRegistry(props: any) {
const { options, children } = props;

const [{ cache, flush }] = React.useState(() => {
const cache = createCache(options);
cache.compat = true;
const prevInsert = cache.insert;
let inserted: string[] = [];
cache.insert = (...args) => {
const serialized = args[1];
if (cache.inserted[serialized.name] === undefined) {
inserted.push(serialized.name);
}
return prevInsert(...args);
};
const flush = () => {
const prevInserted = inserted;
inserted = [];
return prevInserted;
};
return { cache, flush };
});
// Adds top banner/borders for
const AppContainer = ({ children }: { children: React.ReactNode }) => (
<div className='w-full h-full lg:max-h-[660px] lg:max-w-lg lg:border lg:border-solid border-gray-200 lg:rounded-lg lg:shadow-lg flex flex-col relative overflow-hidden lg:mb-0 mb-20 bg-white'>
{/* banner for larger screens */}
<span className='lg:flex hidden bg-secondary text-white p-3 font-medium items-center gap-x-2.5'>
<Image src={`/CircleLogo.svg`} alt='Circle Logo' width={20} height={20} />{" "}
Your app here
</span>
{/* banner for smaller screens */}
<div className='lg:hidden p-4 flex justify-between items-center gradient-banner'>
<span className='flex items-center'>
<Image
src={`/CircleLogo.svg`}
alt='Circle Logo'
className='invert mr-2'
width={20}
height={20}
/>
<Typography level='title-md' className='inline'>
User-Controlled Wallets
</Typography>
</span>

useServerInsertedHTML(() => {
const names = flush();
if (names.length === 0) {
return null;
}
let styles = "";
for (const name of names) {
styles += cache.inserted[name];
}
return (
<style
key={cache.key}
data-emotion={`${cache.key} ${names.join(" ")}`}
dangerouslySetInnerHTML={{
__html: styles,
}}
/>
);
});
<span className='flex gap-x-2'>
<a
href='https://github.com/circlefin/w3s-sample-user-controlled-client-web'
target='_blank'
>
<Button variant='outlined'>Github</Button>
</a>
<a
href='https://developers.circle.com/w3s/docs/sample-applications'
target='_blank'
>
<Button variant='outlined'>Docs</Button>
</a>
</span>
</div>
{children}
</div>
);

return (
<CacheProvider value={cache}>
<CssVarsProvider>
{/* the custom theme is optional */}
<CssBaseline />
{children}
</CssVarsProvider>
</CacheProvider>
);
}
export const metadata: Metadata = {
title: "Programmable Wallet SDK Web Sample App",
description: "An example of how to use Circle's Programmable Wallet SDK",
};
7 changes: 0 additions & 7 deletions app/(pages)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import type { Metadata } from "next";

export const metadata: Metadata = {
title: "Programmable Wallet SDK Web Sample App",
description: "An example of how to use Circle's Programmable Wallet SDK",
};

export default function Home() {
return <></>;
}
36 changes: 16 additions & 20 deletions app/components/Authentication/AuthenticationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,28 +116,24 @@ export const AuthenticationForm: React.FC<AuthenticationFormProps> = ({
};
return (
<Content>
<h1 className="text-center font-bold text-3xl pt-8">
<h1 className='text-center font-bold text-3xl my-2 pt-8'>
{isSignIn ? "Sign In" : "Sign Up"}
</h1>

{!isSignIn && (
<Typography className="text-center text-sm font-medium">{`Don't have an account?`}</Typography>
)}

<form onSubmit={handleSubmit(onSubmit)} className="flex flex-col grow">
<div className="grow space-y-4 mb-4">
<form onSubmit={handleSubmit(onSubmit)} className='flex flex-col'>
<div className='space-y-4'>
<TextField
placeholder="Email"
type="email"
className="flex"
placeholder='Email'
type='email'
className='flex'
error={!!formState.errors.email?.message}
helperText={formState.errors.email?.message}
{...register("email")}
/>
<TextField
placeholder="Password"
placeholder='Password'
type={isMasked ? "password" : "text"}
className="flex"
className='flex'
error={!!formState.errors.password?.message}
helperText={formState.errors.password?.message}
endDecorator={
Expand All @@ -148,25 +144,25 @@ export const AuthenticationForm: React.FC<AuthenticationFormProps> = ({
{...register("password")}
/>
<Button
variant="solid"
className="w-full"
size="lg"
type="submit"
variant='solid'
className='w-full'
size='lg'
type='submit'
loading={loading}
>
{isSignIn ? "Sign In" : "Sign Up"}
</Button>
<p className="text-yellow-500">{formMessage ? formMessage : ""}</p>
<p className='text-yellow-500'>{formMessage ? formMessage : ""}</p>
</div>
</form>

<Typography className="text-center text-sm font-medium">
<Typography className='text-center text-sm font-medium'>
{isSignIn ? "Don't have an account?" : "Already have an account?"}
</Typography>

<Button
variant="plain"
className="w-full"
variant='plain'
className='w-full'
onClick={
isSignIn ? () => router.push("/signup") : () => router.push("/signin")
}
Expand Down
2 changes: 1 addition & 1 deletion app/components/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import React from "react";

export const Content = ({ children }: { children: React.ReactNode }) => {
return (
<div className="px-5 pb-4 h-full flex flex-col gap-y-4 overflow-auto">
<div className='px-5 pb-4 h-full flex flex-col gap-y-4 overflow-auto'>
{children}
</div>
);
Expand Down
52 changes: 52 additions & 0 deletions app/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) 2024, Circle Technologies, LLC. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { Typography } from "@mui/joy";
import Link from "next/link";

export const Footer = () => (
<footer className='absolute bottom-0 flex flex-col lg:flex-row w-screen justify-between p-4 lg:items-center gap-y-2'>
<Typography className='text-neutral-600 text-xs'>
© 2024 Circle Technology Services, LLC. All rights reserved.
</Typography>

<span className='space-x-4 font-semibold'>
<Link
href='https://www.circle.com/en/legal/privacy-policy'
target='_blank'
className='text-xs no-underline'
>
Privacy Policy
</Link>

<Link
href='https://www.circle.com/en/legal/acceptable-use-policy'
target='_blank'
className='text-xs no-underline'
>
Acceptable Use
</Link>

<Link
href='https://www.circle.com/en/legal/cookie-policy'
target='_blank'
className='text-xs no-underline'
>
Cookie Policy
</Link>
</span>
</footer>
);
Loading

0 comments on commit 4a27424

Please sign in to comment.