-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathchat.tsx
226 lines (214 loc) · 7.87 KB
/
chat.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
'use client';
import { Button } from '@frontend/components/button';
import { FC, useCallback, useEffect, useRef, useState } from 'react';
import useSWR from 'swr';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
dayjs.extend(utc);
const ScrollBottom: FC<{ scroll: () => void; reload: boolean }> = (props) => {
useEffect(() => {
props.scroll();
}, [props.reload]);
return null;
};
const SendMessage: FC<{ update: () => void }> = (props) => {
const [value, setValue] = useState('');
const submit = useCallback(
async (e: any) => {
e.preventDefault();
if (value.length < 3) {
return alert('You have to type at least 3 characters');
}
await fetch('/api/dashboard/messages', {
method: 'POST',
body: JSON.stringify({ message: value }),
});
setValue('');
props.update();
},
[value]
);
return (
<form className="flex w-full items-center space-x-2" onSubmit={submit}>
<div className="flex-1 bg-black h-[68px] px-[32px] rounded-[100px]">
<input
className="w-full h-full outline-none text-white bg-transparent"
id="message"
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Message your Squad..."
autoComplete="off"
data-id={43}
/>
</div>
<button
type="submit"
className="flex justify-center items-center cursor-pointer bg-sendButton transition-all hover:shadow-btn w-[68px] h-[68px] rounded-full"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
>
<path
d="M10.4995 13.5002L20.9995 3.00017M10.6271 13.8282L13.2552 20.5862C13.4867 21.1816 13.6025 21.4793 13.7693 21.5662C13.9139 21.6415 14.0862 21.6416 14.2308 21.5664C14.3977 21.4797 14.5139 21.1822 14.7461 20.5871L21.3364 3.69937C21.5461 3.16219 21.6509 2.8936 21.5935 2.72197C21.5437 2.57292 21.4268 2.45596 21.2777 2.40616C21.1061 2.34883 20.8375 2.45364 20.3003 2.66327L3.41258 9.25361C2.8175 9.48584 2.51997 9.60195 2.43326 9.76886C2.35809 9.91354 2.35819 10.0858 2.43353 10.2304C2.52043 10.3972 2.81811 10.513 3.41345 10.7445L10.1715 13.3726C10.2923 13.4196 10.3527 13.4431 10.4036 13.4794C10.4487 13.5115 10.4881 13.551 10.5203 13.5961C10.5566 13.647 10.5801 13.7074 10.6271 13.8282Z"
stroke="black"
strokeOpacity="0.5"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</button>
</form>
);
};
export function Chat() {
const ref = useRef<null>();
const [reload, setReload] = useState(false);
const scroll = useCallback(() => {
const scroll = ref.current;
if (scroll) {
// @ts-ignore
scroll.scrollTop = scroll.scrollHeight;
}
}, [ref]);
const loadChat = useCallback(async () => {
return (
await fetch('/api/dashboard/messages', {
method: 'GET',
})
).json();
}, []);
const { data, isLoading, mutate } = useSWR('messages', loadChat);
if (isLoading) {
return <></>;
}
return (
<div className="w-full mx-auto flex flex-col h-full">
<div className="flex flex-col gap-[12px] flex-1">
<div className="text-[24px] bg-chatGrad rounded-[12px] h-[69px] text-white font-bebas flex justify-center items-center">
CHAT
</div>
<div className="w-full flex-1 bg-[#191919] rounded-[14px] gap-[12px] px-[20px] py-[40px] flex flex-col">
<div
className="gap-[12px] flex-1 overflow-hidden overflow-y-auto flex flex-col"
// @ts-ignore
ref={ref}
>
<div className="flex gap-[8px] items-end pr-[20px]">
<div className="min-w-[40px]">
<img
className="w-[40px] h-[40px] bg-fuchsia-500 rounded-full"
alt="Nevo David"
src="https://avatars.githubusercontent.com/u/100117126?v=4"
/>
</div>
<div className="rounded-[12px] gap-[8px] rounded-bl-none bg-[#2D2D2D] p-[12px] flex flex-col">
<div className="flex gap-[12px] items-center">
<div className="text-[#FBFF14] text-[20px]">Nevo David</div>
<div className="text-[#8e8e8e]">
{dayjs().local().format('hh:mm a')}
</div>
</div>
<div className="text-[20px] font-[300]">
Hi guys welcome to your squad!
<br />
<br />
Make sure you create your{' '}
<a
href="/dashboard/ticket"
className="underline hover:font-bold"
>
personal ticket
</a>{' '}
and share it.
<br />
I will be giving random swag to the people who share.
<br />
<br />
Don{"'"}t forget to check your bonuses, we will add more add
during the competition.
<br />
And of course, follow us on:{' '}
<a
className="underline hover:font-bold"
href="https://whatsapp.com/channel/0029VakC1dbA2pLGYG9Jph1L"
>
WhatsApp
</a>
,{' '}
<a
className="underline hover:font-bold"
href="https://t.me/+KZVCCxksVcpkNmZk"
>
Telegram
</a>
,
<a
className="underline hover:font-bold"
href="https://discord.gg/raSVgQP9vx"
>
Discord
</a>
, and{' '}
<a
className="underline hover:font-bold"
href="https://x.com/devfestai"
>
X
</a>
, to know about everything first.
</div>
</div>
</div>
{data.messages.map(
(p: {
id: string;
message: string;
createdAt: string;
user: {
name: string;
profilePicture: string;
handle: string;
};
}) => (
<div key={p.id} className="flex gap-[8px] items-end pr-[20px]">
<div className="min-w-[40px]">
<img
className="w-[40px] h-[40px] bg-fuchsia-500 rounded-full"
alt={p.user.name}
src={p.user.profilePicture}
/>
</div>
<div className="rounded-[12px] gap-[8px] rounded-bl-none bg-[#2D2D2D] p-[12px] flex flex-col">
<div className="flex gap-[12px] items-center">
<div className="text-[#FBFF14] text-[20px]">
{p.user.name}
</div>
<div className="text-[#8e8e8e]">
{dayjs(p.createdAt).local().format('hh:mm a')}
</div>
</div>
<div className="text-[20px] font-[300]">{p.message}</div>
</div>
</div>
)
)}
<ScrollBottom scroll={scroll} reload={reload} />
</div>
<div className="mt-[20px] flex gap-[8px]">
<SendMessage
update={async () => {
await mutate();
setReload(!reload);
}}
/>
</div>
</div>
</div>
</div>
);
}