Skip to content

Commit

Permalink
update demo
Browse files Browse the repository at this point in the history
  • Loading branch information
m-Ryan committed Sep 25, 2023
1 parent 2ce2184 commit 1c6ca8f
Show file tree
Hide file tree
Showing 72 changed files with 13,736 additions and 86 deletions.
48 changes: 0 additions & 48 deletions demo/src/components/CommercialEmailEditorBanner/index.tsx

This file was deleted.

2 changes: 0 additions & 2 deletions demo/src/components/Frame/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Layout, Menu, Breadcrumb } from '@arco-design/web-react';
import { Stack } from '../Stack';
import { pushEvent } from '@demo/utils/pushEvent';
import { githubButtonGenerate } from '@demo/utils/githubButtonGenerate';
import { CommercialEmailEditorBanner } from '../CommercialEmailEditorBanner';
import { useShowCommercialEditor } from '@demo/hooks/useShowCommercialEditor';

const { SubMenu } = Menu;
Expand Down Expand Up @@ -125,7 +124,6 @@ export default function Frame({
</Stack>

<Stack.Item>
{featureEnabled && <CommercialEmailEditorBanner page='HOME' />}
<Content
style={{
padding: 24,
Expand Down
2 changes: 1 addition & 1 deletion demo/src/hooks/useShowCommercialEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ export const useShowCommercialEditor = () => {
});
}, []);

return { featureEnabled };
return { featureEnabled: featureEnabled || process.env.NODE_ENV === 'development' };
};
17 changes: 17 additions & 0 deletions demo/src/hooks/useShowLiveChat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { posthog } from '@demo/utils/posthog';
import { useEffect, useState } from 'react';

export const useShowLiveChat = () => {
const [featureEnabled, setFeatureEnabled] = useState(false);

useEffect(() => {
posthog.onFeatureFlags(function () {
console.log('posthog.show_live_chat', posthog.isFeatureEnabled('show_live_chat'));
if (posthog.isFeatureEnabled('show_live_chat')) {
setFeatureEnabled(true);
}
});
}, []);

return { showLiveChat: featureEnabled };
};
6 changes: 3 additions & 3 deletions demo/src/pages/Editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ import localesData from 'easy-email-localization/locales/locales.json';
import { Uploader } from '@demo/utils/Uploader';
import axios from 'axios';
import enUS from '@arco-design/web-react/es/locale/en-US';
import { CommercialEmailEditorBanner } from '@demo/components/CommercialEmailEditorBanner';

import { useShowCommercialEditor } from '@demo/hooks/useShowCommercialEditor';

console.log(localesData);
Expand Down Expand Up @@ -518,7 +518,7 @@ export default function Editor() {
<style>{themeStyleText}</style>
<EmailEditorProvider
key={id}
height={featureEnabled ? 'calc(100vh - 128px)' : 'calc(100vh - 68px)'}
height={featureEnabled ? 'calc(100vh - 108px)' : 'calc(100vh - 68px)'}
data={initialValues}
// interactiveStyle={{
// hoverColor: '#78A349',
Expand Down Expand Up @@ -668,7 +668,7 @@ export default function Editor() {
</Stack>
}
/>
{featureEnabled && <CommercialEmailEditorBanner page='EDITOR' />}

<StandardLayout
compact={!smallScene}
categories={defaultCategories}
Expand Down
20 changes: 20 additions & 0 deletions nextjs-demo/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema

# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB (Preview).
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings

DATABASE_URL=""

SECRET='SECRET'

# When deploying to production, set the `NEXTAUTH_URL` environment variable to the canonical URL of your site.
NEXTAUTH_URL='http://localhost:3000'

# GitHub OAuth
GITHUB_ID=""
GITHUB_SECRET=""

# Google Auth
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
3 changes: 3 additions & 0 deletions nextjs-demo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
.next/
.env
16 changes: 16 additions & 0 deletions nextjs-demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
### Install dependence

```sh
pnpm install

```

### Rename .env.example to .env

### install db

npx prisma migrate dev

### Open server

npm run dev
13 changes: 13 additions & 0 deletions nextjs-demo/client/assets/images/empty-email.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nextjs-demo/client/assets/images/iphone.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 70 additions & 0 deletions nextjs-demo/client/components/CommercialBanner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { useShowLiveChat } from '@/client/hooks/useShowLiveChat';
import { pushEvent } from '@/client/utils/pushEvent';
import { Alert } from '@arco-design/web-react';

import React, { useEffect } from 'react';
import { useSessionStorage } from 'react-use';

export const CommercialBanner = ({ page }: { page: 'HOME' | 'EDITOR' }) => {
const [visible, setVisible] = useSessionStorage(
'commercialEmailEditorBannerVisible',
true,
);

const { showLiveChat } = useShowLiveChat();

useEffect(() => {
pushEvent({ event: `Show_Banner_at_${page}` });
}, [page]);

if (!visible) return null;
return (
<Alert
closable
onClose={() => setVisible(false)}
style={{
alignItems: 'flex-start',
}}
banner
content={
<div>
<div>
Is the current Easy Email not meeting <strong>your requirements</strong> ?
It's time to try our more powerful commercial version of the email editor.{' '}
<span>
{showLiveChat ? (
<>
<a
onClick={() => {
pushEvent({ event: `Contact_at_${page}` });
(window as any).$crisp?.push(['do', 'chat:open']);
}}
target='_blank'
style={{ fontSize: 16 }}
>
<strong>Open Live Chat</strong>
</a>
</>
) : (
<>
Contact us for more information. Email:{' '}
<a
onClick={() => {
pushEvent({ event: `Contact_at_${page}` });
}}
target='_blank'
href='mailto:ch.mao@qq.com'
style={{ fontSize: 16 }}
>
<strong>ch.mao@qq.com</strong>
</a>
.
</>
)}
</span>
</div>
</div>
}
></Alert>
);
};
29 changes: 29 additions & 0 deletions nextjs-demo/client/components/FullScreenLoading/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Spin } from "@arco-design/web-react";
import { FC } from "react";

interface LoadingScreenProps {
size?: number;
isFullScreen?: boolean;
}

const FullScreenLoading: FC<LoadingScreenProps> = ({
size = 40,
isFullScreen,
}) => {
return (
<div
style={{
width: isFullScreen ? "100vw" : "100%",
height: isFullScreen ? "100vh" : "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}}
>
<Spin size={size} />
</div>
);
};

export default FullScreenLoading;
65 changes: 65 additions & 0 deletions nextjs-demo/client/components/IframeComponent/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React, { useState } from 'react';
import { useInterval } from 'react-use';
import { createPortal } from 'react-dom';

interface Props
extends React.DetailedHTMLProps<
React.IframeHTMLAttributes<HTMLIFrameElement>,
HTMLIFrameElement
> {
children: React.ReactNode;
title?: string;
onChangeHeight?: (val: number) => void;
windowRef?: (e: Window) => void;
}

export const IframeComponent = ({
children,
title,
windowRef,
style,
onChangeHeight,
...props
}: Props) => {
const [mountNode, setMountNode] = useState<HTMLBodyElement | null>(null);
const [height, setHeight] = useState(0);

const onLoad: React.ReactEventHandler<HTMLIFrameElement> = evt => {
const contentWindow = (evt.target as any)?.contentWindow;
if (!contentWindow) return;
windowRef?.(contentWindow);
const innerBody = contentWindow.document.body;
innerBody.style.backgroundColor = 'transparent';
setMountNode(innerBody);
};

useInterval(() => {
const scrollHeight = mountNode?.scrollHeight || 0;
if (scrollHeight > 0) {
setHeight(scrollHeight);
onChangeHeight && onChangeHeight(scrollHeight);
}
}, 1000);

return (
<iframe
title={title}
srcDoc={
'<!doctype html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"> <head></head> <body> </body> </html>'
}
style={{
height: `${height}px`,
width: '100%',
padding: 0,
margin: 0,
display: 'block',
...style,
}}
frameBorder='none'
{...(props as any)}
onLoad={onLoad}
>
{mountNode && createPortal(children, mountNode)}
</iframe>
);
};
51 changes: 51 additions & 0 deletions nextjs-demo/client/components/Layout/NavBar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';
import { Avatar, Dropdown, Menu } from '@arco-design/web-react';
import { IconPoweroff } from '@arco-design/web-react/icon';

import styles from './style/index.module.less';
import { signOut, useSession } from 'next-auth/react';

export const Navbar: React.FC = () => {
const { data } = useSession();

const user = data?.user;
const droplist = (
<Menu>
<Menu.Item
key='logout'
onClick={() => {
signOut();
}}
>
<IconPoweroff className={styles['dropdown-icon']} />
Logout
</Menu.Item>
<Menu.Item key='email'>{user?.email}</Menu.Item>
</Menu>
);

return (
<div className={styles.navbar}>
<div className={styles.left}>
<div className={styles.logo}>Easy Email</div>
</div>
<ul className={styles.right}>
{user && (
<li>
<Dropdown
droplist={droplist}
position='br'
>
<Avatar
size={32}
style={{ cursor: 'pointer', backgroundColor: '#1d1d3d' }}
>
{(user.name || user.email)?.toUpperCase()}
</Avatar>
</Dropdown>
</li>
)}
</ul>
</div>
);
};
Loading

0 comments on commit 1c6ca8f

Please sign in to comment.