Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Email App Revamp #29

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/email/package.json
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview",
"deploy:vercel": "vercel build --prod && vercel deploy --prebuilt --prod",
@@ -16,6 +16,7 @@
"@privy-io/wagmi": "^0.2.12",
"@pushprotocol/node-core": "^0.0.29",
"@pushprotocol/push-chain": "^0.1.7",
"@pushprotocol/pushchain-ui-kit": "^0.0.8",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-popover": "^1.1.2",
"@radix-ui/react-scroll-area": "^1.2.0",
56 changes: 42 additions & 14 deletions examples/email/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,53 @@
import { usePrivy } from '@privy-io/react-auth';

import { useAppContext } from './context/app-context';
import LoggedInView from './components/logged-in-view';
import Login from './components/login';
import { getBlocksCSSVariables, Spinner, themeConfig } from 'shared-components';

import { createGlobalStyle, ThemeProvider } from 'styled-components';
import AppRoutes from './routes';
import { BrowserRouter } from 'react-router-dom';
import {
ENV,
usePushWalletContext,
WalletProvider,
} from '@pushprotocol/pushchain-ui-kit';

const GlobalStyle = createGlobalStyle`
:root{
/* Font Family */
--font-family: 'FK Grotesk Neu', Helvetica, sans-serif;
/* New blocks theme css variables*/
${(props) => getBlocksCSSVariables(props.theme.blocksTheme)}
}
`;

function App() {
const { ready, authenticated } = usePrivy();
const { pushAccount } = useAppContext();

return (
<>
{ready ? (
<main className="h-screen w-screen">
{authenticated || pushAccount ? <LoggedInView /> : <Login />}
</main>
) : (
<div className="flex flex-col gap-4 items-center justify-center h-screen w-full">
<div className="w-8 h-8 animate-ping bg-primary rounded-full"></div>
<p>Loading</p>
</div>
)}
</>
<ThemeProvider theme={themeConfig.light}>
<BrowserRouter>
<GlobalStyle />
<WalletProvider env={ENV.PROD}>
{/* <AppRoutes account={account} /> */}
{ready ? (
<main className="h-screen w-screen">
<AppRoutes
authenticated={authenticated}
pushAccount={pushAccount}
/>
</main>
) : (
<div className="flex flex-col gap-4 items-center justify-center h-screen w-full">
<Spinner size="extraLarge" variant="primary" />
</div>
)}
</WalletProvider>
</BrowserRouter>
</ThemeProvider>
);
}

Binary file added examples/email/src/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
178 changes: 178 additions & 0 deletions examples/email/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import { useAppContext } from '@/context/app-context';
import { trimAddress } from '@/lib/utils';
import { usePrivy } from '@privy-io/react-auth';
import { TokenBNB, TokenETH, TokenPUSH, TokenSOL } from '@web3icons/react';
import { MenuIcon } from 'lucide-react';
import { FC } from 'react';
import {
Box,
PushLogo,
Text,
Button,
Menu,
Dropdown,
MenuItem,
} from 'shared-components';
import { css } from 'styled-components';

const Header: FC = () => {
const { user, authenticated, logout } = usePrivy();
const { pushAccount, setPushAccount, setSelectedEmail } = useAppContext();

const logoutHandler = () => {
if (pushAccount) {
setPushAccount(null);
} else if (authenticated) {
logout();
}
setSelectedEmail(null);
};

return (
<Box
display="flex"
padding="spacing-none spacing-xs"
alignItems="center"
justifyContent="space-between"
height="68px"
css={css`
border-bottom: 1px solid var(--stroke-secondary);
`}
>
<Box display="flex" alignItems="center" gap="spacing-xs">
<Box display="flex" alignItems="center" gap="spacing-xxs">
<PushLogo height={40} />
<Text variant="h2-bold">Push</Text>
</Box>
<Text
variant="h4-semibold"
css={css`
display: block;
@media (max-width: 768px) {
display: none;
}
`}
>
Email
</Text>
</Box>
<Dropdown
trigger="click"
overlay={
<Menu>
<MenuItem
label={
(pushAccount || (authenticated && user)) && (
<span className="text-sm">
{pushAccount
? trimAddress(pushAccount.split(':')[2])
: user?.wallet?.address &&
trimAddress(user.wallet.address)}
</span>
)
}
icon={
<Box
display="flex"
alignItems="center"
justifyContent="center"
width="20px"
height="20px"
borderRadius="radius-xxs"
backgroundColor="surface-tertiary"
>
{pushAccount ? (
<TokenPUSH color="#202124" />
) : user?.wallet?.chainType === 'solana' ? (
<TokenSOL color="#202124" />
) : user?.wallet?.chainId === 'eip155:56' ? (
<TokenBNB color="#202124" />
) : (
<TokenETH color="#202124" />
)}
</Box>
}
/>
<MenuItem label="Logout" onClick={logoutHandler} />
</Menu>
}
>
<Box
display="flex"
cursor="pointer"
alignItems="center"
css={css`
display: none;
@media (max-width: 768px) {
display: block;
}
`}
>
<MenuIcon height={32} width={32} />
</Box>
</Dropdown>
<Box
display="flex"
alignItems="center"
gap="spacing-xs"
css={css`
@media (max-width: 768px) {
display: none;
}
`}
>
<Button
variant="tertiary"
css={css`
padding: var(--spacing-xs) var(--spacing-sm);
gap: var(--spacing-xxs);
height: 40px;
cursor: default;
`}
leadingIcon={
<Box
display="flex"
alignItems="center"
justifyContent="center"
width="20px"
height="20px"
borderRadius="radius-xxs"
backgroundColor="surface-tertiary"
>
{pushAccount ? (
<TokenPUSH color="#202124" />
) : user?.wallet?.chainType === 'solana' ? (
<TokenSOL color="#202124" />
) : user?.wallet?.chainId === 'eip155:56' ? (
<TokenBNB color="#202124" />
) : (
<TokenETH color="#202124" />
)}
</Box>
}
>
{(pushAccount || (authenticated && user)) && (
<span className="text-sm">
{pushAccount
? trimAddress(pushAccount.split(':')[2])
: user?.wallet?.address && trimAddress(user.wallet.address)}
</span>
)}
</Button>
<Button
variant="tertiary"
css={css`
padding: var(--spacing-xs) var(--spacing-md);
font-size: 14px;
height: 40px;
`}
onClick={logoutHandler}
>
Logout
</Button>
</Box>
</Box>
);
};

export { Header };
78 changes: 59 additions & 19 deletions examples/email/src/components/email-card.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import React from 'react';
import { Card, CardDescription, CardHeader, CardTitle } from './ui/card';
import { Card } from './ui/card';
import { IEmail } from '@/types';
import { useAppContext } from '@/context/app-context';
import { formatTimestamp, trimAddress } from '@/lib/utils';
import { EMAIL_BOX } from '@/constants';
import BlockiesSvg from 'blockies-react-svg';
import { Box, Text } from 'shared-components';
import { css } from 'styled-components';
import { useNavigate } from 'react-router-dom';

const EmailCard: React.FC<IEmail> = ({
from,
@@ -13,34 +17,70 @@ const EmailCard: React.FC<IEmail> = ({
body,
type,
attachments,
txHash,
}) => {
const { setSelectedEmail, selectedEmail } = useAppContext();
const navigate = useNavigate();
const { currTab, setSelectedEmail, selectedEmail } = useAppContext();

return (
<Card
onClick={() => {
setSelectedEmail({ from, to, subject, timestamp, body, attachments });
setSelectedEmail({
from,
to,
subject,
timestamp,
body,
attachments,
txHash,
});
navigate(`/${currTab}/${txHash}`);
}}
className={`cursor-pointer ${
type === EMAIL_BOX.INBOX
? selectedEmail?.from === from && 'bg-primary-foreground'
? selectedEmail?.from === from && 'bg-secondary-foreground'
: selectedEmail?.to === to && 'bg-primary-foreground'
}`}
>
<CardHeader>
<CardTitle>
<div className="flex flex-row justify-between items-center">
<p>{subject}</p>
<p className="text-sm font-light min-w-12">
{formatTimestamp(timestamp.toString())}
</p>
</div>
</CardTitle>
<CardDescription>
{type === EMAIL_BOX.INBOX
? trimAddress(from.split(':')[2])
: to.map((t) => trimAddress(t.split(':')[2])).join(', ')}
</CardDescription>
</CardHeader>
<Box
display="flex"
alignItems="flex-start"
justifyContent="space-between"
width="100%"
>
<Box display="flex" alignItems="center" gap="spacing-xs">
<Box
width="32px"
height="32px"
borderRadius="radius-round"
overflow="hidden"
alignSelf="center"
>
<BlockiesSvg address={from} />
</Box>
<Box>
<Text variant="h5-bold">{subject}</Text>
<Text variant="bes-semibold" color="text-tertiary">
{trimAddress(from)}
</Text>
</Box>
</Box>
<Text variant="c-regular">{formatTimestamp(timestamp.toString())}</Text>
</Box>
<Box>
<Text
variant="bs-regular"
css={css`
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
`}
>
{body}
</Text>
</Box>
</Card>
);
};
8 changes: 3 additions & 5 deletions examples/email/src/components/email-layout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useState } from 'react';
import React from 'react';

import { IEmail } from '@/types';

import NewEmail from './new-email';
import EmailViewer from './email-viewer';
import { useAppContext } from '@/context/app-context';

const EmailLayout: React.FC = () => {
const [replyTo, setReplyTo] = useState<IEmail | undefined>(undefined);
const { setReplyTo } = useAppContext();

const handleReply = (email: IEmail) => {
setReplyTo(email);
@@ -15,8 +15,6 @@ const EmailLayout: React.FC = () => {
return (
<div className="flex flex-col h-full w-full flex-1 ">
<EmailViewer onReply={handleReply} />

<NewEmail replyTo={replyTo} />
</div>
);
};
Loading