Skip to content

Commit 72ac2a1

Browse files
Added @livechat/developer-ui-react. Upgraded NextJs to v14
1 parent ce402ba commit 72ac2a1

File tree

24 files changed

+3657
-1984
lines changed

24 files changed

+3657
-1984
lines changed

.gitignore

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
/node_modules
55
/.pnp
66
.pnp.js
7+
.yarn/install-state.gz
78

89
# testing
910
/coverage
@@ -23,16 +24,13 @@
2324
npm-debug.log*
2425
yarn-debug.log*
2526
yarn-error.log*
26-
.pnpm-debug.log*
2727

2828
# local env files
29-
.env.local
30-
.env.development.local
31-
.env.test.local
32-
.env.production.local
29+
.env*.local
3330

3431
# vercel
3532
.vercel
3633

3734
# typescript
3835
*.tsbuildinfo
36+
next-env.d.ts

.prettierrc

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { LiveChatDetailsProvider } from "@livechat/developer-ui-react";
2+
3+
export default function Layout({
4+
children,
5+
}: Readonly<{
6+
children: React.ReactNode;
7+
}>) {
8+
return <LiveChatDetailsProvider>{children}</LiveChatDetailsProvider>;
9+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
"use client";
2+
3+
import { Fragment, useEffect, useState } from "react";
4+
import { Button, Card } from "@livechat/design-system-react-components";
5+
import {
6+
deleteCustomerProfile,
7+
fetchCustomers,
8+
saveCustomerProfile,
9+
} from "lib/api";
10+
import { useApp, useLiveChatDetails } from "@livechat/developer-ui-react";
11+
12+
export interface CustomerProfile {
13+
[key: string]: {
14+
default_value: string;
15+
};
16+
}
17+
18+
export default function LiveChatChatDetails() {
19+
const { app } = useApp();
20+
const { customerProfile } = useLiveChatDetails();
21+
const [customers, setCustomers] = useState<CustomerProfile>({});
22+
const [isLoading, setIsLoading] = useState(false);
23+
24+
useEffect(() => {
25+
fetchCustomerProfiles();
26+
// eslint-disable-next-line react-hooks/exhaustive-deps
27+
}, []);
28+
29+
const fetchCustomerProfiles = async () => {
30+
const customers = await fetchCustomers(app);
31+
setCustomers(customers);
32+
};
33+
34+
const handleSaveCustomerProfile = async () => {
35+
if (!customerProfile) {
36+
return;
37+
}
38+
39+
setIsLoading(true);
40+
await saveCustomerProfile(app, customerProfile);
41+
await fetchCustomerProfiles();
42+
setIsLoading(false);
43+
};
44+
45+
const handleDeleteCustomerProfile = async () => {
46+
if (!customerProfile) {
47+
return;
48+
}
49+
50+
setIsLoading(true);
51+
await deleteCustomerProfile(app, customerProfile.id);
52+
await fetchCustomerProfiles();
53+
setIsLoading(false);
54+
};
55+
56+
const customerExists = customerProfile && customerProfile?.id in customers;
57+
58+
return (
59+
<div>
60+
<Card title="Customer profile">
61+
{customerProfile ? (
62+
<Fragment>
63+
<ul>
64+
<li>Name: {customerProfile.name}</li>
65+
<li>Email: {customerProfile.email}</li>
66+
<li>Country: {customerProfile.geolocation.country}</li>
67+
<li>Timezone: {customerProfile.geolocation.timezone}</li>
68+
<li>ID: {customerProfile.id}</li>
69+
</ul>
70+
<Button
71+
loading={isLoading}
72+
kind="primary"
73+
onClick={
74+
customerExists
75+
? handleDeleteCustomerProfile
76+
: handleSaveCustomerProfile
77+
}
78+
>
79+
{customerExists ? "Delete customer" : "Save customer"}
80+
</Button>
81+
</Fragment>
82+
) : (
83+
"Loading customer profile"
84+
)}
85+
</Card>
86+
</div>
87+
);
88+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { LiveChatFullscreenProvider } from "@livechat/developer-ui-react";
2+
3+
export default function Layout({
4+
children,
5+
}: Readonly<{
6+
children: React.ReactNode;
7+
}>) {
8+
return <LiveChatFullscreenProvider>{children}</LiveChatFullscreenProvider>;
9+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
"use client";
2+
3+
import { useEffect, useState } from "react";
4+
import { App } from "@livechat/developer-sdk";
5+
import { deleteCustomerProfile, fetchCustomers } from "lib/api";
6+
import { Button } from "@livechat/design-system-react-components";
7+
import { useApp, useLiveChatFullscreen } from "@livechat/developer-ui-react";
8+
9+
interface Customer {
10+
name: string;
11+
email: string;
12+
id: string;
13+
}
14+
15+
export default function Page() {
16+
const { app } = useApp();
17+
const { widget } = useLiveChatFullscreen();
18+
const [notificationsCount, setNotificationsCount] = useState(0);
19+
const [customers, setCustomers] = useState<Customer[]>([]);
20+
21+
const handleFetchCustomers = async (app: App) => {
22+
const customers = await fetchCustomers(app);
23+
const formattedCustomers = Object.keys(customers).map((customer) => ({
24+
name: customers[customer].default_value.split(";")[0],
25+
email: customers[customer].default_value.split(";")[1],
26+
id: customer,
27+
}));
28+
setCustomers(formattedCustomers);
29+
setNotificationsCount(3);
30+
};
31+
32+
const handleDeleteCustomerProfile = async (app: App, customerId: string) => {
33+
await deleteCustomerProfile(app, customerId);
34+
await handleFetchCustomers(app);
35+
};
36+
37+
useEffect(() => {
38+
widget.setNotificationBadge(notificationsCount);
39+
}, [widget, notificationsCount]);
40+
41+
useEffect(() => {
42+
handleFetchCustomers(app);
43+
}, [app]);
44+
45+
return (
46+
<div>
47+
<h1>Customers list</h1>
48+
<table className="customer-list">
49+
<thead>
50+
<tr>
51+
<th>Name</th>
52+
<th>Email</th>
53+
<th>ID</th>
54+
<th />
55+
</tr>
56+
</thead>
57+
<tbody>
58+
{customers.map((customer) => (
59+
<tr key={customer.id}>
60+
<td>{customer.name}</td>
61+
<td>{customer.email}</td>
62+
<td>{customer.id}</td>
63+
<td>
64+
<Button
65+
kind="secondary"
66+
onClick={async () =>
67+
await handleDeleteCustomerProfile(app, customer.id)
68+
}
69+
>
70+
Delete user
71+
</Button>
72+
</td>
73+
</tr>
74+
))}
75+
</tbody>
76+
</table>
77+
</div>
78+
);
79+
}

styles/main.css renamed to app/globals.css

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,18 @@
1-
@import url('@livechat/design-system/dist/design-system.css');
2-
@import url('@livechat/design-system-react-components/dist/style.css');
1+
@import url("@livechat/design-system-react-components/dist/style.css");
2+
@import url("@livechat/developer-ui-react/dist/index.css");
33

44
html,
55
body {
66
padding: 0;
77
margin: 0;
88
font-family: sans-serif;
9+
background-color: #ffffff;
910
}
1011

1112
* {
1213
box-sizing: border-box;
1314
}
1415

15-
.full-screen-loader {
16-
display: flex;
17-
justify-content: center;
18-
align-items: center;
19-
width: 100vw;
20-
height: 100vh;
21-
}
22-
23-
.view-container {
24-
padding: 16px;
25-
}
26-
2716
.customer-list {
2817
width: 100%;
2918
}

app/layout.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import type { Metadata } from "next";
2+
import { Inter } from "next/font/google";
3+
import { AppProvider } from "@livechat/developer-ui-react";
4+
import { AppConfig } from "@livechat/developer-sdk";
5+
import config from "livechat.config.json";
6+
7+
import "./globals.css";
8+
9+
const inter = Inter({ subsets: ["latin"] });
10+
11+
export const metadata: Metadata = {
12+
title: "Developer app template (NextJs)",
13+
};
14+
15+
export default function RootLayout({
16+
children,
17+
}: Readonly<{
18+
children: React.ReactNode;
19+
}>) {
20+
return (
21+
<html lang="en">
22+
<body className={inter.className}>
23+
<AppProvider config={config as unknown as AppConfig}>
24+
{children}
25+
</AppProvider>
26+
</body>
27+
</html>
28+
);
29+
}

components/FullScreenLoader.tsx

Lines changed: 0 additions & 11 deletions
This file was deleted.

components/ViewContainer.tsx

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)