tiefen_space_h5/app/my/editprofile/editPlace/page.jsx

528 lines
17 KiB
React
Raw Normal View History

2024-10-22 17:24:02 +08:00
"use client";
import React, { useState, useEffect } from "react";
import {
List,
Toast,
Image,
Space,
Picker,
TextArea,
Modal,
Mask,
SpinLoading,
Button,
} from "antd-mobile";
import { DragDropContext, Draggable, Droppable } from "@hello-pangea/dnd";
import { useRouter } from "next/navigation";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faAngleLeft,
faAdd,
faEdit,
faTrashCan,
faSortDown,
} from "@fortawesome/free-solid-svg-icons";
import OwnInput from "@/components/OwnInput";
import requireAPI from "@/utils/requireAPI";
import { get } from "@/utils/storeInfo";
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};
const defaultFormData = {
nickname: "",
url: "",
selectedPlatform: [],
};
export default function EditPlace() {
const router = useRouter();
const [formData, setFormData] = useState(defaultFormData);
const [allPlatforms, setAllPlatforms] = useState([]);
const [platform, setPlatform] = useState([]);
const [currentPlat, setcurrentPlat] = useState(null);
//正在提交状态
const [isSubmitting, setIsSubmitting] = useState(false);
const [platformEditable, setPlatformEditable] = useState(false);
useEffect(() => {
getAllPlatforms();
}, []);
const getAllPlatforms = async () => {
try {
const detailData = await requireAPI("POST", "/api/platform/list", {});
if (detailData.ret === -1) {
Toast.show({
icon: "fail",
content: detailData.msg,
position: "top",
});
return;
}
const detailDataValues = Object.entries(detailData.data);
const temAllPlatforms = detailDataValues.map((item) => {
return {
label: item[1].name,
value: {
link_no: parseInt(item[0], 10),
link_name: item[1].name,
link_icon: item[1].icon,
},
};
});
//获取主播当前所有平台
const streamerPlatformData = await requireAPI(
"POST",
"/api/streamer_link/list_by_mid",
{},
true
);
if (streamerPlatformData.ret === -1) {
Toast.show({
icon: "error",
content: streamerPlatformData.msg,
position: "top",
});
return;
}
const streamerPlatList = streamerPlatformData.data.list;
setAllPlatforms(temAllPlatforms);
const platformsWithIcon = streamerPlatList.map((item) => {
return {
...item,
link_icon: detailData.data[item.link_no].icon,
};
});
setPlatform(platformsWithIcon);
} catch (error) {
console.error(error);
}
};
//点击删除按钮
const handleDelete = (index) => {
const updatedPlatform = [...platform];
updatedPlatform.splice(index, 1);
setPlatform(updatedPlatform);
};
const handSubmit = async () => {
const account = get("account");
const newPlatforms = [...platform];
newPlatforms.forEach((item, index) => {
item.order = index + 1;
item.mid = account.mid;
});
try {
//获取主播当前所有平台
const streamerPlatformData = await requireAPI(
"POST",
"/api/streamer_link/list_by_mid",
{},
true
);
if (streamerPlatformData.ret === -1) {
Toast.show({
icon: "fail",
content: streamerPlatformData.msg,
position: "top",
});
return;
}
//删除全部现有平台
const ids = streamerPlatformData.data.list.map((item) => item.id);
if (ids.length !== 0) {
const deleteData = await requireAPI(
"POST",
"/api/streamer_link/delete_batch",
{
body: {
ids: ids,
},
}
);
if (deleteData.ret === -1) {
Toast.show({
icon: "fail",
content: deleteData.msg,
position: "top",
});
return;
}
}
//批量创建新的平台
if (newPlatforms.length === 0) {
Toast.show({
icon: "success",
content: "更改成功",
position: "top",
});
return;
}
const data = await requireAPI("POST", "/api/streamer_link/create_batch", {
body: {
streamer_links: newPlatforms,
},
});
if (data.ret === -1) {
Toast.show({
icon: "fail",
content: data.msg,
position: "top",
});
return;
}
Toast.show({
icon: "success",
content: "更改成功",
position: "top",
});
router.back();
} catch (error) {
console.error(error);
} finally {
setPlatformEditable(false);
setFormData(defaultFormData);
setIsSubmitting(false);
}
};
const handleEditPlatform = (values) => {
if (!values.nickname || !values.selectedPlatform.length || !values.url) {
Toast.show({
icon: "fail",
content: "请完整填写信息",
position: "top",
});
return;
}
if (
values.url.indexOf("http://") == -1 &&
values.url.indexOf("https://") == -1
) {
Toast.show({
icon: "fail",
content: "链接必须以https://或http://开头",
position: "top",
});
return;
}
let newPlatforms = [];
if (!formData.id) {
const currentPlatFormEle = allPlatforms.filter(
(it) => it.label == values.selectedPlatform[0]
)[0];
const newPlatform = {
link_name: values.selectedPlatform[0],
link_icon: currentPlatFormEle.value.link_icon,
link_no: currentPlatFormEle.value.link_no,
nickname: values.nickname,
url: values.url,
};
newPlatforms = platform.concat(newPlatform);
// setIsSubmitting(true);
} else {
const index = platform.findIndex(
(it) => it.link_name == formData.selectedPlatform
);
newPlatforms = [...platform];
newPlatforms[index].link_name = formData.selectedPlatform;
newPlatforms[index] = {
...newPlatforms[index],
link_name: formData.selectedPlatform,
nickname: formData.nickname,
url: formData.url,
};
}
setFormData(defaultFormData);
setPlatform(newPlatforms);
setPlatformEditable(false);
};
const onDragEnd = (result) => {
if (!result.destination) return;
const newList = reorder(
platform,
result.source.index,
result.destination.index
);
setPlatform([...newList]);
};
return (
<div>
{/* 头部标题 */}
<div className="p-4 fixed top-0 z-10 w-full bg-black">
<div className="w-9 h-9 flex items-center justify-center bg-[#FFFFFF1A] rounded-full absolute">
<FontAwesomeIcon
icon={faAngleLeft}
style={{ maxWidth: "12px" }}
size="xl"
onClick={() => {
router.back();
}}
/>
</div>
<p className="text-base text-center leading-9">编辑平台</p>
</div>
{/* 内容 */}
<div className="pt-16 p-4">
<div
className="mt-2 text-sm flex justify-center items-center font-medium border border-dashed border-white rounded-md px-4 py-3"
onClick={() => setPlatformEditable(true)}
>
<FontAwesomeIcon
icon={faAdd}
style={{ maxWidth: "12px" }}
size="xl"
/>
<span className="ml-2">添加</span>
</div>
<List
className="mt-4"
style={{
"--padding-left": 0,
"--padding-right": 0,
"--border-inner": "none",
}}
>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="droppable11">
{(droppableProvided) => (
<div
{...droppableProvided.droppableProps}
ref={droppableProvided.innerRef}
>
{platform.map((item, index) => (
<Draggable
key={item.id + index}
draggableId={(item.id || index).toString()}
index={index}
>
{(provided, snapshot) => (
<div
key={item.name}
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={{
...provided.draggableProps.style,
opacity: snapshot.isDragging ? 0.8 : 1,
}}
>
<div
key={index}
className="w-full grid grid-cols-[auto,20px] gap-4 justify-between bg-[#13121F] rounded-lg p-4 my-2"
>
<div className="text-base font-medium">
<div className="flex items-center">
<span>平台</span>
<div className="flex items-center">
<Image
src={item?.link_icon?.images[0]?.urls[0]}
width={18}
/>
<span className="ml-2">{item.link_name}</span>
</div>
</div>
<p className="flex items-center">
<span>昵称</span>
<span>{item.nickname}</span>
</p>
<p className="flex">
<span className="whitespace-nowrap">
链接
</span>
<span
className="whitespace-normal inline-block"
style={{ overflowWrap: "anywhere" }}
>
{item.url}
</span>
</p>
</div>
<div className="grid grid-rows-[32px,32px] gap-2 items-center">
<div onClick={() => handleDelete(index)}>
<FontAwesomeIcon
icon={faTrashCan}
style={{ maxWidth: "18px" }}
size="xl"
/>
</div>
<div
onClick={() => {
setPlatformEditable(true);
setFormData({
nickname: item.nickname,
url: item.url,
selectedPlatform: item.link_name,
id: item.id,
});
}}
>
<FontAwesomeIcon
icon={faEdit}
style={{ maxWidth: "18px" }}
size="xl"
/>
</div>
</div>
</div>
</div>
)}
</Draggable>
))}
{droppableProvided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
</List>
<div className="fixed bottom-8 flex justify-center w-full">
<Button
size="middle"
shape="rounded"
style={{
"--background-color": "#FF669E",
paddingLeft: "32px",
paddingRight: "32px",
}}
disabled={isSubmitting}
onClick={() => handSubmit()}
>
{isSubmitting ? "正在提交..." : "确认修改"}
</Button>
</div>
</div>
<Modal
visible={platformEditable}
content={
<div className="w-full px-4">
<p className="text-lg font-medium text-center mb-2">
编辑/添加平台
</p>
<div className="flex items-center my-4">
<span className="text-base font-medium mr-1">平台</span>
{!formData.id ? (
<div className="w-1/2">
<Picker
columns={[
[
...allPlatforms
.map((it) => {
return {
label: it.label,
value: it.label,
};
})
.filter((it) => {
return !platform.some(
(el) => el.link_name == it.label
);
}),
],
]}
onSelect={(value) => {
setFormData((old) => ({
...old,
selectedPlatform: value,
}));
}}
value={formData.selectedPlatform}
>
{(items, { open }) => {
return (
<Space
align="center"
direction="horizontal"
justify="center"
onClick={open}
>
{items.every((item) => item === null)
? "未选择"
: items
.map((item) => item?.label ?? "未选择")
.join("")}
<FontAwesomeIcon
icon={faSortDown}
style={{ maxWidth: "12px", marginBottom: 6 }}
size="lg"
/>
</Space>
);
}}
</Picker>
</div>
) : (
<span className="text-base font-medium mr-1">
{formData?.selectedPlatform}
</span>
)}
</div>
<div className="flex items-center my-4">
<span className="text-base font-medium mr-1">昵称</span>
<OwnInput
placeholder="请输入昵称"
onChange={(value) => {
setFormData((old) => ({ ...old, nickname: value }));
}}
value={formData.nickname}
className="border border-[#2c2b2f] font-medium rounded-lg h-10 px-2"
/>
</div>
<div className="flex my-4">
<span className="text-base font-medium mr-1 whitespace-nowrap">
链接
</span>
<TextArea
placeholder="请输入链接"
onChange={(value) => {
setFormData((old) => ({ ...old, url: value }));
}}
value={formData.url}
style={{
"--placeholder-color": "#FFFFFF80",
"--font-size": "16px",
}}
className="border border-[#2c2b2f] font-medium rounded-lg h-24 p-2 "
/>
</div>
</div>
}
actions={[
{
key: "confirm",
text: "确认",
className: "rounded-full",
style: {
background: "#FF669E",
border: "none",
borderRadius: "100px",
},
primary: true,
},
{
key: "cancle",
text: "取消",
style: { color: "#ffffff80" },
},
]}
onAction={(action, index) => {
if (action.key == "confirm") {
handleEditPlatform(formData);
} else {
setPlatformEditable(false);
setFormData(defaultFormData);
}
}}
></Modal>
<Mask visible={isSubmitting}>
<div className="w-full h-screen flex justify-center items-center">
<SpinLoading color="default" />
</div>
</Mask>
</div>
);
}