|
1 | 1 | import React, { useState, useEffect } from "react";
|
2 | 2 | import { useChannelState } from "../../context/ChannelState";
|
3 | 3 | import { supabase } from "../../SupabaseClient";
|
4 |
| -import { ClipboardIcon, PlusIcon } from "@heroicons/react/24/outline"; |
| 4 | +import { |
| 5 | + ArrowDownCircleIcon, |
| 6 | + Bars2Icon, |
| 7 | + ClipboardIcon, |
| 8 | + PlusCircleIcon, |
| 9 | + PlusIcon, |
| 10 | + TrashIcon, |
| 11 | +} from "@heroicons/react/24/outline"; |
5 | 12 | import copy from "clipboard-copy";
|
| 13 | +import { |
| 14 | + CountryDropdown, |
| 15 | + RegionDropdown, |
| 16 | + CountryRegionData, |
| 17 | +} from "react-country-region-selector"; |
| 18 | +import { uid } from "uid"; |
6 | 19 |
|
7 | 20 | const Header = () => {
|
8 | 21 | return (
|
@@ -38,12 +51,14 @@ const BasicInfo = () => {
|
38 | 51 | const { data: info1 } = await supabase
|
39 | 52 | .from("channels")
|
40 | 53 | .update({ ...channelDetails })
|
41 |
| - .eq("uid", currentChannel?.uid).select(); |
| 54 | + .eq("uid", currentChannel?.uid) |
| 55 | + .select(); |
42 | 56 | const { data: info2 } = await supabase
|
43 | 57 | .from("channelInfo")
|
44 | 58 | .update({ ...channelInfo })
|
45 |
| - .eq("channelRef", currentChannel?.uid).select(); |
46 |
| - console.log(info1, info2) |
| 59 | + .eq("channelRef", currentChannel?.uid) |
| 60 | + .select(); |
| 61 | + console.log(info1, info2); |
47 | 62 | };
|
48 | 63 |
|
49 | 64 | return (
|
@@ -128,32 +143,166 @@ const BasicInfo = () => {
|
128 | 143 | />
|
129 | 144 | </div>
|
130 | 145 |
|
131 |
| - <button |
132 |
| - className="link-btn text-center bg-blue-500 text-white w-28" onClick={() => Save()}>Publish</button> |
| 146 | + <div className="flex flex-col gap-2"> |
| 147 | + <h2 |
| 148 | + htmlFor="description" |
| 149 | + className="text-semibold text-gray-700 dark:text-gray-200 text-lg" |
| 150 | + > |
| 151 | + Location |
| 152 | + </h2> |
| 153 | + <CountryDropdown |
| 154 | + className="py-2 px-4 text-lg bg-transparent dark:text-white border border-gray-400/40 dark:border-gray-200/40 p-2 rounded-2xl" |
| 155 | + value={channelInfo?.location} |
| 156 | + onChange={(val) => setChannelInfo({ ...channelInfo, location: val })} |
| 157 | + /> |
| 158 | + </div> |
| 159 | + |
| 160 | + <button |
| 161 | + className="link-btn text-center dark:text-white bg-blue-500 text-white w-28" |
| 162 | + onClick={() => Save()} |
| 163 | + > |
| 164 | + Publish |
| 165 | + </button> |
| 166 | + </div> |
| 167 | + ); |
| 168 | +}; |
| 169 | + |
| 170 | +const AddNew = ({ newLink, links, setShowAddDialog, channelRef, setLinks, setNewLink }) => { |
| 171 | + const Remove = () => { |
| 172 | + setNewLink({ name: "", url: "" }); |
| 173 | + setShowAddDialog(false); |
| 174 | + }; |
| 175 | + |
| 176 | + const Add = async () => { |
| 177 | + const { name, url } = newLink; |
| 178 | + const isCorrect = name?.trim() !== '' && url?.trim() !== ''; |
| 179 | + console.log(isCorrect) |
| 180 | + if (isCorrect) { |
| 181 | + // adding from the backend |
| 182 | + await supabase.from('socialLinks').insert({ |
| 183 | + name: name, |
| 184 | + url: url, |
| 185 | + channelRef: channelRef |
| 186 | + }) |
| 187 | + setLinks([...links, newLink]); |
| 188 | + setNewLink({ name: "", url: "" }); |
| 189 | + setShowAddDialog(false); |
| 190 | + } |
| 191 | + }; |
| 192 | + return ( |
| 193 | + <div className="flex items-center gap-2 w-full"> |
| 194 | + <Bars2Icon className="icon" /> |
| 195 | + <input |
| 196 | + className="input flex-1 dark:text-gray-200" |
| 197 | + placeholder="Link title (required)" |
| 198 | + value={newLink?.name} |
| 199 | + onChange={(e) => setNewLink({ ...newLink, name: e.target.value })} |
| 200 | + /> |
| 201 | + <input |
| 202 | + className="input flex-1 dark:text-gray-200" |
| 203 | + placeholder="URL (required)" |
| 204 | + value={newLink?.url} |
| 205 | + onChange={(e) => setNewLink({ ...newLink, url: e.target.value })} |
| 206 | + /> |
| 207 | + <TrashIcon className="clickable-icon" onClick={() => Remove()} /> |
| 208 | + <PlusCircleIcon className="clickable-icon" onClick={() => Add()} /> |
| 209 | + </div> |
| 210 | + ); |
| 211 | +}; |
| 212 | + |
| 213 | +const Link = ({ name, url, id, setLinks }) => { |
| 214 | + const [newName, setNewName] = useState(name); |
| 215 | + const [newUrl, setNewUrl] = useState(url); |
| 216 | + const Remove = async () => { |
| 217 | + // deleting from the backend |
| 218 | + await supabase.from("socialLinks").delete().eq("id", id); |
| 219 | + const { data } = await supabase.from("socialLinks").select(); |
| 220 | + setLinks(data); |
| 221 | + }; |
| 222 | + |
| 223 | + const Update = async () => { |
| 224 | + // updating from the backend |
| 225 | + const { data } = await supabase |
| 226 | + .from("socialLinks") |
| 227 | + .update({ name: newName, url: newUrl }) |
| 228 | + .eq("id", id) |
| 229 | + .select(); |
| 230 | + const newData = data[0]; |
| 231 | + const { name, url } = newData; |
| 232 | + setNewName(name); |
| 233 | + setNewUrl(url); |
| 234 | + }; |
| 235 | + return ( |
| 236 | + <div className="flex items-center gap-2 w-full"> |
| 237 | + <Bars2Icon className="icon" /> |
| 238 | + <input |
| 239 | + className="input flex-1 dark:text-gray-200" |
| 240 | + placeholder="Link title (required)" |
| 241 | + value={newName} |
| 242 | + onChange={(e) => setNewName(e.target.value)} |
| 243 | + /> |
| 244 | + <input |
| 245 | + className="input flex-1 dark:text-gray-200" |
| 246 | + placeholder="URL (required)" |
| 247 | + value={newUrl} |
| 248 | + onChange={(e) => setNewUrl(e.target.value)} |
| 249 | + /> |
| 250 | + <TrashIcon className="clickable-icon" onClick={() => Remove()} /> |
| 251 | + <ArrowDownCircleIcon |
| 252 | + className="clickable-icon" |
| 253 | + onClick={() => Update()} |
| 254 | + /> |
133 | 255 | </div>
|
134 | 256 | );
|
135 | 257 | };
|
136 | 258 |
|
137 | 259 | const Links = () => {
|
138 | 260 | const [showAddDialog, setShowAddDialog] = useState(false);
|
139 | 261 | const [links, setLinks] = useState();
|
140 |
| - const {currentChannel} = useChannelState(); |
| 262 | + const [newLink, setNewLink] = useState({ |
| 263 | + name: "", |
| 264 | + url: "", |
| 265 | + }); |
| 266 | + const { currentChannel } = useChannelState(); |
141 | 267 |
|
142 | 268 | useEffect(() => {
|
143 |
| - const fetchLinks = async() => { |
144 |
| - const {data} = await supabase.from('links').select().eq('channelRef', currentChannel?.uid) |
| 269 | + const fetchLinks = async () => { |
| 270 | + const { data } = await supabase |
| 271 | + .from("socialLinks") |
| 272 | + .select() |
| 273 | + .eq("channelRef", currentChannel?.uid); |
145 | 274 | setLinks(data);
|
146 |
| - } |
| 275 | + }; |
147 | 276 | fetchLinks();
|
148 |
| - }, []) |
| 277 | + }, []); |
149 | 278 | return (
|
150 | 279 | <div className="flex flex-col space-y-3 my-2">
|
151 | 280 | <h3 className="text-bold text-lg my-2 text-gray-700">Links</h3>
|
152 | 281 | <span className="text-sm text-gray-500 dark:text-gray-300">
|
153 | 282 | Add links to sites you want to share with your viewers
|
154 | 283 | </span>
|
155 | 284 | <button
|
156 |
| - className="link-btn text-left flex items-center w-40"><PlusIcon className='icon'/> Add Link</button> |
| 285 | + onClick={() => setShowAddDialog(true)} |
| 286 | + className="link-btn text-left flex items-center w-40" |
| 287 | + > |
| 288 | + <PlusIcon className="icon" /> Add Link |
| 289 | + </button> |
| 290 | + |
| 291 | + <div className="flex flex-col gap-2 w-[85vw]"> |
| 292 | + {showAddDialog && ( |
| 293 | + <AddNew |
| 294 | + newLink={newLink} |
| 295 | + setNewLink={setNewLink} |
| 296 | + setLinks={setLinks} |
| 297 | + links={links} |
| 298 | + setShowAddDialog={setShowAddDialog} |
| 299 | + channelRef={currentChannel?.uid} |
| 300 | + /> |
| 301 | + )} |
| 302 | + {links?.map((link) => ( |
| 303 | + <Link key={uid()} setLinks={setLinks} {...link} /> |
| 304 | + ))} |
| 305 | + </div> |
157 | 306 | </div>
|
158 | 307 | );
|
159 | 308 | };
|
|
0 commit comments