feat: add website add and code tip
This commit is contained in:
parent
4a4c25c2eb
commit
7363fcf440
26
src/client/components/ModalButton.tsx
Normal file
26
src/client/components/ModalButton.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { Button, ButtonProps, Modal, ModalProps } from 'antd';
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
interface ModalButtonProps {
|
||||||
|
buttonProps: Omit<ButtonProps, 'onClick'>;
|
||||||
|
modalProps: Omit<ModalProps, 'open' | 'onCancel'>;
|
||||||
|
}
|
||||||
|
export const ModalButton: React.FC<ModalButtonProps> = React.memo((props) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
{...props.buttonProps}
|
||||||
|
onClick={() => setIsOpen((state) => !state)}
|
||||||
|
/>
|
||||||
|
<Modal
|
||||||
|
onOk={() => setIsOpen(false)}
|
||||||
|
{...props.modalProps}
|
||||||
|
open={isOpen}
|
||||||
|
onCancel={() => setIsOpen(false)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
ModalButton.displayName = 'ModalButton';
|
@ -1,9 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
BarChartOutlined,
|
BarChartOutlined,
|
||||||
|
CodeOutlined,
|
||||||
EditOutlined,
|
EditOutlined,
|
||||||
PlusOutlined,
|
PlusOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { Button, Form, Input, Modal, Table } from 'antd';
|
import { Button, Form, Input, Modal, Table, Typography } from 'antd';
|
||||||
import { ColumnsType } from 'antd/es/table';
|
import { ColumnsType } from 'antd/es/table';
|
||||||
import React, { useMemo, useState } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
@ -19,6 +20,7 @@ import { useUserStore } from '../store/user';
|
|||||||
import { useEvent } from '../hooks/useEvent';
|
import { useEvent } from '../hooks/useEvent';
|
||||||
import { useNavigate } from 'react-router';
|
import { useNavigate } from 'react-router';
|
||||||
import { PageHeader } from './PageHeader';
|
import { PageHeader } from './PageHeader';
|
||||||
|
import { ModalButton } from './ModalButton';
|
||||||
|
|
||||||
export const WebsiteList: React.FC = React.memo(() => {
|
export const WebsiteList: React.FC = React.memo(() => {
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
@ -110,9 +112,36 @@ const WebsiteListTable: React.FC<{ workspaceId: string }> = React.memo(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'action',
|
key: 'action',
|
||||||
render: (record) => {
|
render: (_, record) => {
|
||||||
|
const trackScript = `<script async src="${location.origin}/tracker.js" data-website-id="${record.id}"></script>`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex gap-2 justify-end">
|
<div className="flex gap-2 justify-end">
|
||||||
|
<ModalButton
|
||||||
|
buttonProps={{
|
||||||
|
icon: <CodeOutlined />,
|
||||||
|
children: 'Code',
|
||||||
|
}}
|
||||||
|
modalProps={{
|
||||||
|
children: (
|
||||||
|
<div>
|
||||||
|
<div>Tracking code</div>
|
||||||
|
<div className="text-sm opacity-60">
|
||||||
|
Add this code into your website head script
|
||||||
|
</div>
|
||||||
|
<Typography.Paragraph
|
||||||
|
copyable={{
|
||||||
|
format: 'text/plain',
|
||||||
|
text: trackScript,
|
||||||
|
}}
|
||||||
|
className="h-[96px] flex p-2 rounded bg-black bg-opacity-5 border border-black border-opacity-10"
|
||||||
|
>
|
||||||
|
<span>{trackScript}</span>
|
||||||
|
</Typography.Paragraph>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
icon={<EditOutlined />}
|
icon={<EditOutlined />}
|
||||||
onClick={() => handleEdit(record.id)}
|
onClick={() => handleEdit(record.id)}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { Fragment, useMemo, useState } from 'react';
|
import React, { Fragment, useMemo, useState } from 'react';
|
||||||
import { ArrowRightOutlined, EditOutlined } from '@ant-design/icons';
|
import { ArrowRightOutlined, EditOutlined } from '@ant-design/icons';
|
||||||
import { Button, Divider } from 'antd';
|
import { Button, Divider, Empty } from 'antd';
|
||||||
import { WebsiteOverview } from '../components/website/WebsiteOverview';
|
import { WebsiteOverview } from '../components/website/WebsiteOverview';
|
||||||
import { useCurrentWorkspace } from '../store/user';
|
import { useCurrentWorkspace } from '../store/user';
|
||||||
import { Loading } from '../components/Loading';
|
import { Loading } from '../components/Loading';
|
||||||
@ -11,6 +11,7 @@ import { useEvent } from '../hooks/useEvent';
|
|||||||
import arrayMove from 'array-move';
|
import arrayMove from 'array-move';
|
||||||
import SortableList, { SortableItem } from 'react-easy-sort';
|
import SortableList, { SortableItem } from 'react-easy-sort';
|
||||||
import { defaultErrorHandler, defaultSuccessHandler, trpc } from '../api/trpc';
|
import { defaultErrorHandler, defaultSuccessHandler, trpc } from '../api/trpc';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
export const Dashboard: React.FC = React.memo(() => {
|
export const Dashboard: React.FC = React.memo(() => {
|
||||||
const workspace = useCurrentWorkspace();
|
const workspace = useCurrentWorkspace();
|
||||||
@ -31,13 +32,15 @@ export const Dashboard: React.FC = React.memo(() => {
|
|||||||
<div className="h-20 flex items-center">
|
<div className="h-20 flex items-center">
|
||||||
<div className="text-2xl flex-1">Dashboard</div>
|
<div className="text-2xl flex-1">Dashboard</div>
|
||||||
<div>
|
<div>
|
||||||
<Button
|
{websiteList.length !== 0 && (
|
||||||
icon={<EditOutlined />}
|
<Button
|
||||||
size="large"
|
icon={<EditOutlined />}
|
||||||
onClick={() => setIsEditLayout((state) => !state)}
|
size="large"
|
||||||
>
|
onClick={() => setIsEditLayout((state) => !state)}
|
||||||
{isEditLayout ? 'Done' : 'Edit'}
|
>
|
||||||
</Button>
|
{isEditLayout ? 'Done' : 'Edit'}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -57,6 +60,19 @@ export const Dashboard: React.FC = React.memo(() => {
|
|||||||
</SortableList>
|
</SortableList>
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
|
{websiteList.length === 0 && (
|
||||||
|
<Empty
|
||||||
|
description={
|
||||||
|
<div>
|
||||||
|
<div>There is no website has been created</div>
|
||||||
|
<Link to="/settings/websites">
|
||||||
|
<Button>Add webiste</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{websiteList.map((website, i) => (
|
{websiteList.map((website, i) => (
|
||||||
<Fragment key={website.id}>
|
<Fragment key={website.id}>
|
||||||
{i !== 0 && <Divider />}
|
{i !== 0 && <Divider />}
|
||||||
|
Loading…
Reference in New Issue
Block a user