forked from Qortal/q-share
Copy button added to FileContent.tsx
Share button is bigger and Icon is primary app color Minor fixes to imports
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "qtube",
|
||||
"name": "qshare",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,624 +0,0 @@
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import {
|
||||
AddCoverImageButton,
|
||||
AddLogoIcon,
|
||||
CoverImagePreview,
|
||||
CrowdfundActionButton,
|
||||
CrowdfundActionButtonRow,
|
||||
CustomInputField,
|
||||
CustomSelect,
|
||||
LogoPreviewRow,
|
||||
ModalBody,
|
||||
NewCrowdfundTitle,
|
||||
StyledButton,
|
||||
TimesIcon,
|
||||
} from "./Upload-styles.tsx";
|
||||
import {
|
||||
Box,
|
||||
FormControl,
|
||||
InputLabel,
|
||||
MenuItem,
|
||||
Modal,
|
||||
OutlinedInput,
|
||||
Select,
|
||||
SelectChangeEvent,
|
||||
Typography,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import ShortUniqueId from "short-unique-id";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import AddBoxIcon from "@mui/icons-material/AddBox";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
|
||||
import { setNotification } from "../../state/features/notificationsSlice";
|
||||
import { objectToBase64, uint8ArrayToBase64 } from "../../utils/toBase64";
|
||||
import { RootState } from "../../state/store";
|
||||
import {
|
||||
upsertFilesBeginning,
|
||||
addToHashMap,
|
||||
upsertFiles,
|
||||
setEditFile,
|
||||
updateFile,
|
||||
updateInHashMap,
|
||||
setEditPlaylist,
|
||||
} from "../../state/features/fileSlice.ts";
|
||||
import ImageUploader from "../common/ImageUploader";
|
||||
import {
|
||||
QSHARE_PLAYLIST_BASE,
|
||||
QSHARE_FILE_BASE,
|
||||
} from "../../constants/Identifiers.ts";
|
||||
import { Playlists } from "../Playlists/Playlists";
|
||||
import { PlaylistListEdit } from "../PlaylistListEdit/PlaylistListEdit";
|
||||
import { TextEditor } from "../common/TextEditor/TextEditor";
|
||||
import { extractTextFromHTML } from "../common/TextEditor/utils";
|
||||
import {
|
||||
firstCategories,
|
||||
secondCategories,
|
||||
} from "../../constants/Categories/1stCategories.ts";
|
||||
|
||||
const uid = new ShortUniqueId();
|
||||
const shortuid = new ShortUniqueId({ length: 5 });
|
||||
|
||||
interface NewCrowdfundProps {
|
||||
editId?: string;
|
||||
editContent?: null | {
|
||||
title: string;
|
||||
user: string;
|
||||
coverImage: string | null;
|
||||
};
|
||||
}
|
||||
|
||||
interface VideoFile {
|
||||
file: File;
|
||||
title: string;
|
||||
description: string;
|
||||
coverImage?: string;
|
||||
}
|
||||
export const EditPlaylist = () => {
|
||||
const theme = useTheme();
|
||||
const dispatch = useDispatch();
|
||||
const username = useSelector((state: RootState) => state.auth?.user?.name);
|
||||
const userAddress = useSelector(
|
||||
(state: RootState) => state.auth?.user?.address
|
||||
);
|
||||
const editVideoProperties = useSelector(
|
||||
(state: RootState) => state.file.editPlaylistProperties
|
||||
);
|
||||
const [playlistData, setPlaylistData] = useState<any>(null);
|
||||
const [title, setTitle] = useState<string>("");
|
||||
const [description, setDescription] = useState<string>("");
|
||||
const [coverImage, setCoverImage] = useState<string>("");
|
||||
const [videos, setVideos] = useState([]);
|
||||
const [selectedCategoryVideos, setSelectedCategoryVideos] =
|
||||
useState<any>(null);
|
||||
const [selectedSubCategoryVideos, setSelectedSubCategoryVideos] =
|
||||
useState<any>(null);
|
||||
|
||||
const isNew = useMemo(() => {
|
||||
return editVideoProperties?.mode === "new";
|
||||
}, [editVideoProperties]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isNew) {
|
||||
setPlaylistData({
|
||||
videos: [],
|
||||
});
|
||||
}
|
||||
}, [isNew]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (editVideoProperties) {
|
||||
// const descriptionString = editVideoProperties?.description || "";
|
||||
// // Splitting the string at the asterisks
|
||||
// const parts = descriptionString.split("**");
|
||||
|
||||
// // The part within the asterisks
|
||||
// const extractedString = parts[1];
|
||||
|
||||
// // The part after the last asterisks
|
||||
// const description = parts[2] || ""; // Using '|| '' to handle cases where there is no text after the last **
|
||||
// setTitle(editVideoProperties?.title || "");
|
||||
// setDescription(editVideoProperties?.fullDescription || "");
|
||||
// setCoverImage(editVideoProperties?.videoImage || "");
|
||||
|
||||
// // Split the extracted string into key-value pairs
|
||||
// const keyValuePairs = extractedString.split(";");
|
||||
|
||||
// // Initialize variables to hold the category and subcategory values
|
||||
// let category, subcategory;
|
||||
|
||||
// // Loop through each key-value pair
|
||||
// keyValuePairs.forEach((pair) => {
|
||||
// const [key, value] = pair.split(":");
|
||||
|
||||
// // Check the key and assign the value to the appropriate variable
|
||||
// if (key === "category") {
|
||||
// category = value;
|
||||
// } else if (key === "subcategory") {
|
||||
// subcategory = value;
|
||||
// }
|
||||
// });
|
||||
|
||||
// if(category){
|
||||
// const selectedOption = categories.find((option) => option.id === +category);
|
||||
// setSelectedCategoryVideos(selectedOption || null);
|
||||
// }
|
||||
|
||||
// if(subcategory){
|
||||
// const selectedOption = categories.find((option) => option.id === +subcategory);
|
||||
// setSelectedCategoryVideos(selectedOption || null);
|
||||
// }
|
||||
|
||||
// }
|
||||
// }, [editVideoProperties]);
|
||||
|
||||
const checkforPlaylist = React.useCallback(async videoList => {
|
||||
try {
|
||||
const combinedData: any = {};
|
||||
const videos = [];
|
||||
if (videoList) {
|
||||
for (const vid of videoList) {
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&identifier=${vid.identifier}&limit=1&includemetadata=true&reverse=true&name=${vid.name}&exactmatchnames=true&offset=0`;
|
||||
const response = await fetch(url, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
const responseDataSearchVid = await response.json();
|
||||
|
||||
if (responseDataSearchVid?.length > 0) {
|
||||
let resourceData2 = responseDataSearchVid[0];
|
||||
videos.push(resourceData2);
|
||||
}
|
||||
}
|
||||
}
|
||||
combinedData.videos = videos;
|
||||
setPlaylistData(combinedData);
|
||||
} catch (error) {}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (editVideoProperties) {
|
||||
setTitle(editVideoProperties?.title || "");
|
||||
|
||||
if (editVideoProperties?.htmlDescription) {
|
||||
setDescription(editVideoProperties?.htmlDescription);
|
||||
} else if (editVideoProperties?.description) {
|
||||
const paragraph = `<p>${editVideoProperties?.description}</p>`;
|
||||
setDescription(paragraph);
|
||||
}
|
||||
setCoverImage(editVideoProperties?.image || "");
|
||||
setVideos(editVideoProperties?.videos || []);
|
||||
|
||||
if (editVideoProperties?.category) {
|
||||
const selectedOption = firstCategories.find(
|
||||
option => option.id === +editVideoProperties.category
|
||||
);
|
||||
setSelectedCategoryVideos(selectedOption || null);
|
||||
}
|
||||
|
||||
if (
|
||||
editVideoProperties?.category &&
|
||||
editVideoProperties?.subcategory &&
|
||||
secondCategories[+editVideoProperties?.category]
|
||||
) {
|
||||
const selectedOption = secondCategories[
|
||||
+editVideoProperties?.category
|
||||
]?.find(option => option.id === +editVideoProperties.subcategory);
|
||||
setSelectedSubCategoryVideos(selectedOption || null);
|
||||
}
|
||||
|
||||
if (editVideoProperties?.videos) {
|
||||
checkforPlaylist(editVideoProperties?.videos);
|
||||
}
|
||||
}
|
||||
}, [editVideoProperties]);
|
||||
|
||||
const onClose = () => {
|
||||
setTitle("");
|
||||
setDescription("");
|
||||
setVideos([]);
|
||||
setPlaylistData(null);
|
||||
setSelectedCategoryVideos(null);
|
||||
setSelectedSubCategoryVideos(null);
|
||||
setCoverImage("");
|
||||
dispatch(setEditPlaylist(null));
|
||||
};
|
||||
|
||||
async function publishQDNResource() {
|
||||
try {
|
||||
if (!title) throw new Error("Please enter a title");
|
||||
if (!description) throw new Error("Please enter a description");
|
||||
if (!coverImage) throw new Error("Please select cover image");
|
||||
if (!selectedCategoryVideos) throw new Error("Please select a category");
|
||||
|
||||
if (!editVideoProperties) return;
|
||||
if (!userAddress) throw new Error("Unable to locate user address");
|
||||
let errorMsg = "";
|
||||
let name = "";
|
||||
if (username) {
|
||||
name = username;
|
||||
}
|
||||
if (!name) {
|
||||
errorMsg =
|
||||
"Cannot publish without access to your name. Please authenticate.";
|
||||
}
|
||||
|
||||
if (!isNew && editVideoProperties?.user !== username) {
|
||||
errorMsg = "Cannot publish another user's resource";
|
||||
}
|
||||
|
||||
if (errorMsg) {
|
||||
dispatch(
|
||||
setNotification({
|
||||
msg: errorMsg,
|
||||
alertType: "error",
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
const category = selectedCategoryVideos.id;
|
||||
const subcategory = selectedSubCategoryVideos?.id || "";
|
||||
|
||||
const videoStructured = playlistData.videos.map(item => {
|
||||
const descriptionVid = item?.metadata?.description;
|
||||
if (!descriptionVid) throw new Error("cannot find video code");
|
||||
|
||||
// Split the string by ';'
|
||||
let parts = descriptionVid.split(";");
|
||||
|
||||
// Initialize a variable to hold the code value
|
||||
let codeValue = "";
|
||||
|
||||
// Loop through the parts to find the one that starts with 'code:'
|
||||
for (let part of parts) {
|
||||
if (part.startsWith("code:")) {
|
||||
codeValue = part.split(":")[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!codeValue) throw new Error("cannot find video code");
|
||||
|
||||
return {
|
||||
identifier: item.identifier,
|
||||
name: item.name,
|
||||
service: item.service,
|
||||
code: codeValue,
|
||||
};
|
||||
});
|
||||
const id = uid();
|
||||
|
||||
let commentsId = editVideoProperties?.id;
|
||||
|
||||
if (isNew) {
|
||||
commentsId = `${QSHARE_PLAYLIST_BASE}_cm_${id}`;
|
||||
}
|
||||
const stringDescription = extractTextFromHTML(description);
|
||||
|
||||
const playlistObject: any = {
|
||||
title,
|
||||
version: 1,
|
||||
description: stringDescription,
|
||||
htmlDescription: description,
|
||||
image: coverImage,
|
||||
videos: videoStructured,
|
||||
commentsId: commentsId,
|
||||
category,
|
||||
subcategory,
|
||||
};
|
||||
|
||||
const codes = videoStructured.map(item => `c:${item.code};`).join("");
|
||||
let metadescription =
|
||||
`**category:${category};subcategory:${subcategory};${codes}**` +
|
||||
stringDescription.slice(0, 120);
|
||||
|
||||
const crowdfundObjectToBase64 = await objectToBase64(playlistObject);
|
||||
// Description is obtained from raw data
|
||||
|
||||
let identifier = editVideoProperties?.id;
|
||||
const sanitizeTitle = title
|
||||
.replace(/[^a-zA-Z0-9\s-]/g, "")
|
||||
.replace(/\s+/g, "-")
|
||||
.replace(/-+/g, "-")
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
if (isNew) {
|
||||
identifier = `${QSHARE_PLAYLIST_BASE}${sanitizeTitle.slice(0, 30)}_${id}`;
|
||||
}
|
||||
const requestBodyJson: any = {
|
||||
action: "PUBLISH_QDN_RESOURCE",
|
||||
name: username,
|
||||
service: "PLAYLIST",
|
||||
data64: crowdfundObjectToBase64,
|
||||
title: title.slice(0, 50),
|
||||
description: metadescription,
|
||||
identifier: identifier,
|
||||
tag1: QSHARE_FILE_BASE,
|
||||
};
|
||||
|
||||
await qortalRequest(requestBodyJson);
|
||||
if (isNew) {
|
||||
const objectToStore = {
|
||||
title: title.slice(0, 50),
|
||||
description: metadescription,
|
||||
id: identifier,
|
||||
service: "PLAYLIST",
|
||||
name: username,
|
||||
...playlistObject,
|
||||
};
|
||||
dispatch(updateFile(objectToStore));
|
||||
dispatch(updateInHashMap(objectToStore));
|
||||
} else {
|
||||
dispatch(
|
||||
updateFile({
|
||||
...editVideoProperties,
|
||||
...playlistObject,
|
||||
})
|
||||
);
|
||||
dispatch(
|
||||
updateInHashMap({
|
||||
...editVideoProperties,
|
||||
...playlistObject,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
onClose();
|
||||
} catch (error: any) {
|
||||
let notificationObj: any = null;
|
||||
if (typeof error === "string") {
|
||||
notificationObj = {
|
||||
msg: error || "Failed to publish update",
|
||||
alertType: "error",
|
||||
};
|
||||
} else if (typeof error?.error === "string") {
|
||||
notificationObj = {
|
||||
msg: error?.error || "Failed to publish update",
|
||||
alertType: "error",
|
||||
};
|
||||
} else {
|
||||
notificationObj = {
|
||||
msg: error?.message || "Failed to publish update",
|
||||
alertType: "error",
|
||||
};
|
||||
}
|
||||
if (!notificationObj) return;
|
||||
dispatch(setNotification(notificationObj));
|
||||
|
||||
throw new Error("Failed to publish update");
|
||||
}
|
||||
}
|
||||
|
||||
const handleOnchange = (index: number, type: string, value: string) => {
|
||||
// setFiles((prev) => {
|
||||
// let formattedValue = value
|
||||
// console.log({type})
|
||||
// if(type === 'title'){
|
||||
// formattedValue = value.replace(/[^a-zA-Z0-9\s]/g, "")
|
||||
// }
|
||||
// const copyFiles = [...prev];
|
||||
// copyFiles[index] = {
|
||||
// ...copyFiles[index],
|
||||
// [type]: formattedValue,
|
||||
// };
|
||||
// return copyFiles;
|
||||
// });
|
||||
};
|
||||
|
||||
const handleOptionCategoryChangeVideos = (
|
||||
event: SelectChangeEvent<string>
|
||||
) => {
|
||||
const optionId = event.target.value;
|
||||
const selectedOption = firstCategories.find(
|
||||
option => option.id === +optionId
|
||||
);
|
||||
setSelectedCategoryVideos(selectedOption || null);
|
||||
};
|
||||
const handleOptionSubCategoryChangeVideos = (
|
||||
event: SelectChangeEvent<string>,
|
||||
subcategories: any[]
|
||||
) => {
|
||||
const optionId = event.target.value;
|
||||
const selectedOption = subcategories.find(
|
||||
option => option.id === +optionId
|
||||
);
|
||||
setSelectedSubCategoryVideos(selectedOption || null);
|
||||
};
|
||||
|
||||
const removeVideo = index => {
|
||||
const copyData = structuredClone(playlistData);
|
||||
copyData.videos.splice(index, 1);
|
||||
setPlaylistData(copyData);
|
||||
};
|
||||
|
||||
const addVideo = data => {
|
||||
if (playlistData?.videos?.length > 9) {
|
||||
dispatch(
|
||||
setNotification({
|
||||
msg: "Max 10 videos per playlist",
|
||||
alertType: "error",
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
const copyData = structuredClone(playlistData);
|
||||
copyData.videos = [...copyData.videos, { ...data }];
|
||||
setPlaylistData(copyData);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
open={!!editVideoProperties}
|
||||
aria-labelledby="modal-title"
|
||||
aria-describedby="modal-description"
|
||||
>
|
||||
<ModalBody>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
{isNew ? (
|
||||
<NewCrowdfundTitle>Create new playlist</NewCrowdfundTitle>
|
||||
) : (
|
||||
<NewCrowdfundTitle>Update Playlist properties</NewCrowdfundTitle>
|
||||
)}
|
||||
</Box>
|
||||
<>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<FormControl fullWidth sx={{ marginBottom: 2 }}>
|
||||
<InputLabel id="Category">Select a Category</InputLabel>
|
||||
<Select
|
||||
labelId="Category"
|
||||
input={<OutlinedInput label="Select a Category" />}
|
||||
value={selectedCategoryVideos?.id || ""}
|
||||
onChange={handleOptionCategoryChangeVideos}
|
||||
>
|
||||
{firstCategories.map(option => (
|
||||
<MenuItem key={option.id} value={option.id}>
|
||||
{option.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
{selectedCategoryVideos &&
|
||||
secondCategories[selectedCategoryVideos?.id] && (
|
||||
<FormControl fullWidth sx={{ marginBottom: 2 }}>
|
||||
<InputLabel id="Category">Select a Sub-Category</InputLabel>
|
||||
<Select
|
||||
labelId="Sub-Category"
|
||||
input={<OutlinedInput label="Select a Sub-Category" />}
|
||||
value={selectedSubCategoryVideos?.id || ""}
|
||||
onChange={e =>
|
||||
handleOptionSubCategoryChangeVideos(
|
||||
e,
|
||||
secondCategories[selectedCategoryVideos?.id]
|
||||
)
|
||||
}
|
||||
>
|
||||
{secondCategories[selectedCategoryVideos.id].map(
|
||||
option => (
|
||||
<MenuItem key={option.id} value={option.id}>
|
||||
{option.name}
|
||||
</MenuItem>
|
||||
)
|
||||
)}
|
||||
</Select>
|
||||
</FormControl>
|
||||
)}
|
||||
</Box>
|
||||
<React.Fragment>
|
||||
{!coverImage ? (
|
||||
<ImageUploader onPick={(img: string) => setCoverImage(img)}>
|
||||
<AddCoverImageButton variant="contained">
|
||||
Add Cover Image
|
||||
<AddLogoIcon
|
||||
sx={{
|
||||
height: "25px",
|
||||
width: "auto",
|
||||
}}
|
||||
></AddLogoIcon>
|
||||
</AddCoverImageButton>
|
||||
</ImageUploader>
|
||||
) : (
|
||||
<LogoPreviewRow>
|
||||
<CoverImagePreview src={coverImage} alt="logo" />
|
||||
<TimesIcon
|
||||
color={theme.palette.text.primary}
|
||||
onClickFunc={() => setCoverImage("")}
|
||||
height={"32"}
|
||||
width={"32"}
|
||||
></TimesIcon>
|
||||
</LogoPreviewRow>
|
||||
)}
|
||||
<CustomInputField
|
||||
name="title"
|
||||
label="Title of playlist"
|
||||
variant="filled"
|
||||
value={title}
|
||||
onChange={e => {
|
||||
const value = e.target.value;
|
||||
const formattedValue = value.replace(
|
||||
/[^a-zA-Z0-9\s-_!?]/g,
|
||||
""
|
||||
);
|
||||
setTitle(formattedValue);
|
||||
}}
|
||||
inputProps={{ maxLength: 180 }}
|
||||
required
|
||||
/>
|
||||
{/* <CustomInputField
|
||||
name="description"
|
||||
label="Describe your playlist in a few words"
|
||||
variant="filled"
|
||||
value={description}
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
inputProps={{ maxLength: 10000 }}
|
||||
multiline
|
||||
maxRows={3}
|
||||
required
|
||||
/> */}
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "18px",
|
||||
}}
|
||||
>
|
||||
Description of playlist
|
||||
</Typography>
|
||||
<TextEditor
|
||||
inlineContent={description}
|
||||
setInlineContent={value => {
|
||||
setDescription(value);
|
||||
}}
|
||||
/>
|
||||
</React.Fragment>
|
||||
|
||||
<PlaylistListEdit
|
||||
playlistData={playlistData}
|
||||
removeVideo={removeVideo}
|
||||
addVideo={addVideo}
|
||||
/>
|
||||
</>
|
||||
|
||||
<CrowdfundActionButtonRow>
|
||||
<CrowdfundActionButton
|
||||
onClick={() => {
|
||||
onClose();
|
||||
}}
|
||||
variant="contained"
|
||||
color="error"
|
||||
>
|
||||
Cancel
|
||||
</CrowdfundActionButton>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<CrowdfundActionButton
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
publishQDNResource();
|
||||
}}
|
||||
>
|
||||
Publish
|
||||
</CrowdfundActionButton>
|
||||
</Box>
|
||||
</CrowdfundActionButtonRow>
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,586 +0,0 @@
|
||||
import { styled } from "@mui/system";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
Box,
|
||||
Button,
|
||||
Grid,
|
||||
Rating,
|
||||
TextField,
|
||||
Typography,
|
||||
Select
|
||||
} from "@mui/material";
|
||||
import AddPhotoAlternateIcon from "@mui/icons-material/AddPhotoAlternate";
|
||||
import { TimesSVG } from "../../assets/svgs/TimesSVG";
|
||||
|
||||
export const DoubleLine = styled(Typography)`
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
export const MainContainer = styled(Grid)({
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
alignItems: "flex-start",
|
||||
justifyContent: "center",
|
||||
margin: 0,
|
||||
});
|
||||
|
||||
export const MainCol = styled(Grid)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
padding: "20px",
|
||||
}));
|
||||
|
||||
export const CreateContainer = styled(Box)(({ theme }) => ({
|
||||
position: "fixed",
|
||||
bottom: "20px",
|
||||
right: "20px",
|
||||
cursor: "pointer",
|
||||
background: theme.palette.background.default,
|
||||
width: "50px",
|
||||
height: "50px",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
borderRadius: "50%",
|
||||
}));
|
||||
|
||||
export const ModalBody = styled(Box)(({ theme }) => ({
|
||||
position: "absolute",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
borderRadius: "4px",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
width: "75%",
|
||||
maxWidth: "900px",
|
||||
padding: "15px 35px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "17px",
|
||||
overflowY: "auto",
|
||||
maxHeight: "95vh",
|
||||
boxShadow:
|
||||
theme.palette.mode === "dark"
|
||||
? "0px 4px 5px 0px hsla(0,0%,0%,0.14), 0px 1px 10px 0px hsla(0,0%,0%,0.12), 0px 2px 4px -1px hsla(0,0%,0%,0.2)"
|
||||
: "rgba(99, 99, 99, 0.2) 0px 2px 8px 0px",
|
||||
"&::-webkit-scrollbar-track": {
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
},
|
||||
"&::-webkit-scrollbar-track:hover": {
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
},
|
||||
"&::-webkit-scrollbar": {
|
||||
width: "16px",
|
||||
height: "10px",
|
||||
backgroundColor: theme.palette.mode === "light" ? "#f6f8fa" : "#292d3e",
|
||||
},
|
||||
"&::-webkit-scrollbar-thumb": {
|
||||
backgroundColor: theme.palette.mode === "light" ? "#d3d9e1" : "#575757",
|
||||
borderRadius: "8px",
|
||||
backgroundClip: "content-box",
|
||||
border: "4px solid transparent",
|
||||
},
|
||||
"&::-webkit-scrollbar-thumb:hover": {
|
||||
backgroundColor: theme.palette.mode === "light" ? "#b7bcc4" : "#474646",
|
||||
},
|
||||
}));
|
||||
|
||||
export const NewCrowdfundTitle = styled(Typography)(({ theme }) => ({
|
||||
fontWeight: 400,
|
||||
fontFamily: "Raleway",
|
||||
fontSize: "25px",
|
||||
userSelect: "none",
|
||||
}));
|
||||
export const NewCrowdFundFont = styled(Typography)(({ theme }) => ({
|
||||
fontWeight: 400,
|
||||
fontFamily: "Raleway",
|
||||
fontSize: "18px",
|
||||
userSelect: "none",
|
||||
}));
|
||||
export const NewCrowdfundTimeDescription = styled(Typography)(({ theme }) => ({
|
||||
fontWeight: 400,
|
||||
fontFamily: "Raleway",
|
||||
fontSize: "18px",
|
||||
userSelect: "none",
|
||||
fontStyle: "italic",
|
||||
textDecoration: "underline",
|
||||
}));
|
||||
|
||||
export const CustomInputField = styled(TextField)(({ theme }) => ({
|
||||
fontFamily: "Mulish",
|
||||
fontSize: "19px",
|
||||
letterSpacing: "0px",
|
||||
fontWeight: 400,
|
||||
color: theme.palette.text.primary,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
borderColor: theme.palette.background.paper,
|
||||
"& label": {
|
||||
color: theme.palette.mode === "light" ? "#808183" : "#edeef0",
|
||||
fontFamily: "Mulish",
|
||||
fontSize: "19px",
|
||||
letterSpacing: "0px",
|
||||
fontWeight: 400,
|
||||
},
|
||||
"& label.Mui-focused": {
|
||||
color: theme.palette.mode === "light" ? "#A0AAB4" : "#d7d8da",
|
||||
},
|
||||
"& .MuiInput-underline:after": {
|
||||
borderBottomColor: theme.palette.mode === "light" ? "#B2BAC2" : "#c9cccf",
|
||||
},
|
||||
"& .MuiOutlinedInput-root": {
|
||||
"& fieldset": {
|
||||
borderColor: "#E0E3E7",
|
||||
},
|
||||
"&:hover fieldset": {
|
||||
borderColor: "#B2BAC2",
|
||||
},
|
||||
"&.Mui-focused fieldset": {
|
||||
borderColor: "#6F7E8C",
|
||||
},
|
||||
},
|
||||
"& .MuiInputBase-root": {
|
||||
fontFamily: "Mulish",
|
||||
fontSize: "19px",
|
||||
letterSpacing: "0px",
|
||||
fontWeight: 400,
|
||||
},
|
||||
"& [class$='-MuiFilledInput-root']": {
|
||||
padding: "30px 12px 8px",
|
||||
},
|
||||
"& .MuiFilledInput-root:after": {
|
||||
borderBottomColor: theme.palette.secondary.main,
|
||||
},
|
||||
}));
|
||||
|
||||
|
||||
|
||||
export const CrowdfundTitle = styled(Typography)(({ theme }) => ({
|
||||
fontFamily: "Copse",
|
||||
letterSpacing: "1px",
|
||||
fontWeight: 400,
|
||||
fontSize: "20px",
|
||||
color: theme.palette.text.primary,
|
||||
userSelect: "none",
|
||||
wordBreak: "break-word",
|
||||
}));
|
||||
|
||||
export const CrowdfundSubTitleRow = styled(Box)({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
width: "100%",
|
||||
flexDirection: "row",
|
||||
});
|
||||
|
||||
export const CrowdfundSubTitle = styled(Typography)(({ theme }) => ({
|
||||
fontFamily: "Copse",
|
||||
letterSpacing: "1px",
|
||||
fontWeight: 400,
|
||||
fontSize: "17px",
|
||||
color: theme.palette.text.primary,
|
||||
userSelect: "none",
|
||||
wordBreak: "break-word",
|
||||
borderBottom: `1px solid ${theme.palette.text.primary}`,
|
||||
paddingBottom: "1.5px",
|
||||
width: "fit-content",
|
||||
textDecoration: "none",
|
||||
}));
|
||||
|
||||
export const CrowdfundDescription = styled(Typography)(({ theme }) => ({
|
||||
fontFamily: "Raleway",
|
||||
fontSize: "16px",
|
||||
color: theme.palette.text.primary,
|
||||
userSelect: "none",
|
||||
wordBreak: "break-word",
|
||||
}));
|
||||
|
||||
export const Spacer = ({ height }: any) => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
height: height,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const StyledCardHeaderComment = styled(Box)({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
gap: "5px",
|
||||
padding: "7px 0px",
|
||||
});
|
||||
export const StyledCardCol = styled(Box)({
|
||||
display: "flex",
|
||||
overflow: "hidden",
|
||||
flexDirection: "column",
|
||||
gap: "2px",
|
||||
alignItems: "flex-start",
|
||||
width: "100%",
|
||||
});
|
||||
|
||||
export const StyledCardColComment = styled(Box)({
|
||||
display: "flex",
|
||||
overflow: "hidden",
|
||||
flexDirection: "column",
|
||||
gap: "2px",
|
||||
alignItems: "flex-start",
|
||||
width: "100%",
|
||||
});
|
||||
|
||||
export const AuthorTextComment = styled(Typography)({
|
||||
fontFamily: "Raleway, sans-serif",
|
||||
fontSize: "16px",
|
||||
lineHeight: "1.2",
|
||||
});
|
||||
|
||||
export const AddLogoIcon = styled(AddPhotoAlternateIcon)(({ theme }) => ({
|
||||
color: "#fff",
|
||||
height: "25px",
|
||||
width: "auto",
|
||||
}));
|
||||
|
||||
export const CoverImagePreview = styled("img")(({ theme }) => ({
|
||||
width: "100px",
|
||||
height: "100px",
|
||||
objectFit: "contain",
|
||||
userSelect: "none",
|
||||
borderRadius: "3px",
|
||||
marginBottom: "10px",
|
||||
}));
|
||||
|
||||
export const LogoPreviewRow = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "10px",
|
||||
}));
|
||||
|
||||
export const TimesIcon = styled(TimesSVG)(({ theme }) => ({
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
borderRadius: "50%",
|
||||
padding: "5px",
|
||||
transition: "all 0.2s ease-in-out",
|
||||
"&:hover": {
|
||||
cursor: "pointer",
|
||||
scale: "1.1",
|
||||
},
|
||||
}));
|
||||
|
||||
export const CrowdfundCardTitle = styled(DoubleLine)(({ theme }) => ({
|
||||
fontFamily: "Montserrat",
|
||||
fontSize: "24px",
|
||||
letterSpacing: "-0.3px",
|
||||
userSelect: "none",
|
||||
marginBottom: "auto",
|
||||
textAlign: "center",
|
||||
"@media (max-width: 650px)": {
|
||||
fontSize: "18px",
|
||||
},
|
||||
}));
|
||||
|
||||
export const CrowdfundUploadDate = styled(Typography)(({ theme }) => ({
|
||||
fontFamily: "Montserrat",
|
||||
fontSize: "12px",
|
||||
letterSpacing: "0.2px",
|
||||
color: theme.palette.text.primary,
|
||||
userSelect: "none",
|
||||
}));
|
||||
|
||||
export const CATContainer = styled(Box)(({ theme }) => ({
|
||||
position: "relative",
|
||||
display: "flex",
|
||||
padding: "15px",
|
||||
flexDirection: "column",
|
||||
gap: "20px",
|
||||
justifyContent: "center",
|
||||
width: "100%",
|
||||
alignItems: "center",
|
||||
}));
|
||||
|
||||
export const AddCrowdFundButton = styled(Button)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
textTransform: "none",
|
||||
padding: "10px 25px",
|
||||
fontSize: "15px",
|
||||
gap: "8px",
|
||||
color: "#ffffff",
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86",
|
||||
border: "none",
|
||||
borderRadius: "5px",
|
||||
transition: "all 0.3s ease-in-out",
|
||||
"&:hover": {
|
||||
cursor: "pointer",
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.dark : "#217e6d",
|
||||
},
|
||||
}));
|
||||
|
||||
export const EditCrowdFundButton = styled(Button)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
textTransform: "none",
|
||||
padding: "5px 12px",
|
||||
gap: "8px",
|
||||
color: "#ffffff",
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86",
|
||||
border: "none",
|
||||
borderRadius: "5px",
|
||||
transition: "all 0.3s ease-in-out",
|
||||
"&:hover": {
|
||||
cursor: "pointer",
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.dark : "#217e6d",
|
||||
},
|
||||
}));
|
||||
|
||||
export const CrowdfundListWrapper = styled(Box)(({ theme }) => ({
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
marginTop: "0px",
|
||||
background: theme.palette.background.default,
|
||||
}));
|
||||
|
||||
export const CrowdfundTitleRow = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
width: "100%",
|
||||
gap: "10px",
|
||||
}));
|
||||
|
||||
export const CrowdfundPageTitle = styled(Typography)(({ theme }) => ({
|
||||
fontFamily: "Copse",
|
||||
fontSize: "35px",
|
||||
fontWeight: 400,
|
||||
letterSpacing: "1px",
|
||||
userSelect: "none",
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const CrowdfundStatusRow = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
fontFamily: "Mulish",
|
||||
fontSize: "21px",
|
||||
fontWeight: 400,
|
||||
letterSpacing: 0,
|
||||
border: `1px solid ${theme.palette.text.primary}`,
|
||||
borderRadius: "8px",
|
||||
padding: "15px 25px",
|
||||
userSelect: "none",
|
||||
}));
|
||||
|
||||
export const CrowdfundDescriptionRow = styled(Box)({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
width: "100%",
|
||||
fontFamily: "Montserrat",
|
||||
fontSize: "18px",
|
||||
fontWeight: 400,
|
||||
letterSpacing: 0,
|
||||
});
|
||||
|
||||
export const AboutMyCrowdfund = styled(Typography)(({ theme }) => ({
|
||||
fontFamily: "Copse",
|
||||
fontSize: "23px",
|
||||
fontWeight: 400,
|
||||
letterSpacing: "1px",
|
||||
userSelect: "none",
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const CrowdfundInlineContentRow = styled(Box)({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
width: "100%",
|
||||
});
|
||||
|
||||
export const CrowdfundInlineContent = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
fontFamily: "Mulish",
|
||||
fontSize: "19px",
|
||||
fontWeight: 400,
|
||||
letterSpacing: 0,
|
||||
userSelect: "none",
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const CrowdfundAccordion = styled(Accordion)(({ theme }) => ({
|
||||
backgroundColor: theme.palette.primary.light,
|
||||
"& .Mui-expanded": {
|
||||
minHeight: "auto !important",
|
||||
},
|
||||
}));
|
||||
|
||||
export const CrowdfundAccordionSummary = styled(AccordionSummary)({
|
||||
height: "50px",
|
||||
"& .Mui-expanded": {
|
||||
margin: "0px !important",
|
||||
},
|
||||
});
|
||||
|
||||
export const CrowdfundAccordionFont = styled(Typography)(({ theme }) => ({
|
||||
fontFamily: "Mulish",
|
||||
fontSize: "20px",
|
||||
fontWeight: 400,
|
||||
letterSpacing: "0px",
|
||||
color: theme.palette.text.primary,
|
||||
userSelect: "none",
|
||||
}));
|
||||
|
||||
export const CrowdfundAccordionDetails = styled(AccordionDetails)({
|
||||
padding: "0px 16px 16px 16px",
|
||||
});
|
||||
|
||||
export const AddCoverImageButton = styled(Button)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
fontFamily: "Montserrat",
|
||||
fontSize: "16px",
|
||||
fontWeight: 400,
|
||||
letterSpacing: "0.2px",
|
||||
color: "white",
|
||||
gap: "5px",
|
||||
}));
|
||||
|
||||
export const CoverImage = styled("img")({
|
||||
width: "100%",
|
||||
height: "250px",
|
||||
objectFit: "cover",
|
||||
objectPosition: "center",
|
||||
});
|
||||
|
||||
export const CrowdfundActionButtonRow = styled(Box)({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
width: "100%",
|
||||
});
|
||||
|
||||
export const CrowdfundActionButton = styled(Button)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
fontFamily: "Montserrat",
|
||||
fontSize: "16px",
|
||||
fontWeight: 400,
|
||||
letterSpacing: "0.2px",
|
||||
color: "white",
|
||||
gap: "5px",
|
||||
}));
|
||||
|
||||
export const BackToHomeButton = styled(Button)(({ theme }) => ({
|
||||
position: "absolute",
|
||||
top: "20px",
|
||||
left: "20px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
fontFamily: "Montserrat",
|
||||
fontSize: "13px",
|
||||
fontWeight: 400,
|
||||
letterSpacing: "0.2px",
|
||||
color: "white",
|
||||
gap: "5px",
|
||||
padding: "5px 10px",
|
||||
backgroundColor: theme.palette.secondary.main,
|
||||
transition: "all 0.3s ease-in-out",
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.secondary.dark,
|
||||
cursor: "pointer",
|
||||
},
|
||||
}));
|
||||
|
||||
export const CrowdfundLoaderRow = styled(Box)({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
gap: "10px",
|
||||
padding: "10px",
|
||||
});
|
||||
|
||||
export const RatingContainer = styled(Box)({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
padding: "1px 5px",
|
||||
borderRadius: "5px",
|
||||
backgroundColor: "transparent",
|
||||
transition: "all 0.3s ease-in-out",
|
||||
"&:hover": {
|
||||
cursor: "pointer",
|
||||
backgroundColor: "#e4ddddac",
|
||||
},
|
||||
});
|
||||
|
||||
export const StyledRating = styled(Rating)({
|
||||
fontSize: "28px",
|
||||
});
|
||||
|
||||
export const NoReviewsFont = styled(Typography)(({ theme }) => ({
|
||||
fontFamily: "Mulish",
|
||||
fontWeight: 400,
|
||||
letterSpacing: 0,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
export const StyledButton = styled(Button)(({ theme }) => ({
|
||||
fontWeight: 600,
|
||||
color: theme.palette.text.primary
|
||||
}))
|
||||
|
||||
export const CustomSelect = styled(Select)(({ theme }) => ({
|
||||
fontFamily: "Mulish",
|
||||
fontSize: "19px",
|
||||
letterSpacing: "0px",
|
||||
fontWeight: 400,
|
||||
color: theme.palette.text.primary,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
'& .MuiSelect-select': {
|
||||
padding: '12px',
|
||||
fontFamily: "Mulish",
|
||||
fontSize: "19px",
|
||||
letterSpacing: "0px",
|
||||
fontWeight: 400,
|
||||
borderRadius: theme.shape.borderRadius, // Match border radius
|
||||
},
|
||||
'&:before': {
|
||||
// Underline style
|
||||
borderBottomColor: theme.palette.mode === "light" ? "#B2BAC2" : "#c9cccf",
|
||||
},
|
||||
'&:after': {
|
||||
// Underline style when focused
|
||||
borderBottomColor: theme.palette.secondary.main,
|
||||
},
|
||||
'& .MuiOutlinedInput-root': {
|
||||
'& fieldset': {
|
||||
borderColor: "#E0E3E7",
|
||||
},
|
||||
'&:hover fieldset': {
|
||||
borderColor: "#B2BAC2",
|
||||
},
|
||||
'&.Mui-focused fieldset': {
|
||||
borderColor: "#6F7E8C",
|
||||
},
|
||||
},
|
||||
'& .MuiInputBase-root': {
|
||||
fontFamily: "Mulish",
|
||||
fontSize: "19px",
|
||||
letterSpacing: "0px",
|
||||
fontWeight: 400,
|
||||
color: theme.palette.text.primary,
|
||||
},
|
||||
}));
|
||||
@@ -290,7 +290,15 @@ export const PublishFile = ({ editId, editContent }: NewCrowdfundProps) => {
|
||||
{editId ? null : (
|
||||
<StyledButton
|
||||
color="primary"
|
||||
startIcon={<AddBoxIcon />}
|
||||
startIcon={
|
||||
<AddBoxIcon
|
||||
sx={{
|
||||
color: "#66C3FE",
|
||||
width: "40px",
|
||||
height: "40px",
|
||||
}}
|
||||
/>
|
||||
}
|
||||
onClick={() => {
|
||||
setIsOpen(true);
|
||||
}}
|
||||
|
||||
@@ -9,10 +9,11 @@ import {
|
||||
Rating,
|
||||
TextField,
|
||||
Typography,
|
||||
Select
|
||||
Select,
|
||||
} from "@mui/material";
|
||||
import AddPhotoAlternateIcon from "@mui/icons-material/AddPhotoAlternate";
|
||||
import { TimesSVG } from "../../assets/svgs/TimesSVG";
|
||||
import { fontSizeSmall } from "../../constants/Misc.ts";
|
||||
|
||||
export const DoubleLine = styled(Typography)`
|
||||
display: -webkit-box;
|
||||
@@ -67,9 +68,9 @@ export const ModalBody = styled(Box)(({ theme }) => ({
|
||||
overflowY: "auto",
|
||||
maxHeight: "95vh",
|
||||
boxShadow:
|
||||
theme.palette.mode === "dark"
|
||||
? "0px 4px 5px 0px hsla(0,0%,0%,0.14), 0px 1px 10px 0px hsla(0,0%,0%,0.12), 0px 2px 4px -1px hsla(0,0%,0%,0.2)"
|
||||
: "rgba(99, 99, 99, 0.2) 0px 2px 8px 0px",
|
||||
theme.palette.mode === "dark"
|
||||
? "0px 4px 5px 0px hsla(0,0%,0%,0.14), 0px 1px 10px 0px hsla(0,0%,0%,0.12), 0px 2px 4px -1px hsla(0,0%,0%,0.2)"
|
||||
: "rgba(99, 99, 99, 0.2) 0px 2px 8px 0px",
|
||||
"&::-webkit-scrollbar-track": {
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
},
|
||||
@@ -159,8 +160,6 @@ export const CustomInputField = styled(TextField)(({ theme }) => ({
|
||||
},
|
||||
}));
|
||||
|
||||
|
||||
|
||||
export const CrowdfundTitle = styled(Typography)(({ theme }) => ({
|
||||
fontFamily: "Copse",
|
||||
letterSpacing: "1px",
|
||||
@@ -203,11 +202,11 @@ export const CrowdfundDescription = styled(Typography)(({ theme }) => ({
|
||||
|
||||
export const Spacer = ({ height }: any) => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
height: height,
|
||||
}}
|
||||
/>
|
||||
<Box
|
||||
sx={{
|
||||
height: height,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -314,14 +313,14 @@ export const AddCrowdFundButton = styled(Button)(({ theme }) => ({
|
||||
gap: "8px",
|
||||
color: "#ffffff",
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86",
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86",
|
||||
border: "none",
|
||||
borderRadius: "5px",
|
||||
transition: "all 0.3s ease-in-out",
|
||||
"&:hover": {
|
||||
cursor: "pointer",
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.dark : "#217e6d",
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.dark : "#217e6d",
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -333,14 +332,14 @@ export const EditCrowdFundButton = styled(Button)(({ theme }) => ({
|
||||
gap: "8px",
|
||||
color: "#ffffff",
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86",
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86",
|
||||
border: "none",
|
||||
borderRadius: "5px",
|
||||
transition: "all 0.3s ease-in-out",
|
||||
"&:hover": {
|
||||
cursor: "pointer",
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.dark : "#217e6d",
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.dark : "#217e6d",
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -540,8 +539,9 @@ export const NoReviewsFont = styled(Typography)(({ theme }) => ({
|
||||
export const StyledButton = styled(Button)(({ theme }) => ({
|
||||
fontWeight: 600,
|
||||
color: theme.palette.text.primary,
|
||||
fontFamily: "Cairo"
|
||||
}))
|
||||
fontFamily: "Cairo",
|
||||
fontSize: fontSizeSmall,
|
||||
}));
|
||||
|
||||
export const CustomSelect = styled(Select)(({ theme }) => ({
|
||||
fontFamily: "Mulish",
|
||||
@@ -550,38 +550,38 @@ export const CustomSelect = styled(Select)(({ theme }) => ({
|
||||
fontWeight: 400,
|
||||
color: theme.palette.text.primary,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
'& .MuiSelect-select': {
|
||||
padding: '12px',
|
||||
"& .MuiSelect-select": {
|
||||
padding: "12px",
|
||||
fontFamily: "Mulish",
|
||||
fontSize: "19px",
|
||||
letterSpacing: "0px",
|
||||
fontWeight: 400,
|
||||
borderRadius: theme.shape.borderRadius, // Match border radius
|
||||
},
|
||||
'&:before': {
|
||||
"&:before": {
|
||||
// Underline style
|
||||
borderBottomColor: theme.palette.mode === "light" ? "#B2BAC2" : "#c9cccf",
|
||||
},
|
||||
'&:after': {
|
||||
"&:after": {
|
||||
// Underline style when focused
|
||||
borderBottomColor: theme.palette.secondary.main,
|
||||
},
|
||||
'& .MuiOutlinedInput-root': {
|
||||
'& fieldset': {
|
||||
"& .MuiOutlinedInput-root": {
|
||||
"& fieldset": {
|
||||
borderColor: "#E0E3E7",
|
||||
},
|
||||
'&:hover fieldset': {
|
||||
"&:hover fieldset": {
|
||||
borderColor: "#B2BAC2",
|
||||
},
|
||||
'&.Mui-focused fieldset': {
|
||||
"&.Mui-focused fieldset": {
|
||||
borderColor: "#6F7E8C",
|
||||
},
|
||||
},
|
||||
'& .MuiInputBase-root': {
|
||||
"& .MuiInputBase-root": {
|
||||
fontFamily: "Mulish",
|
||||
fontSize: "19px",
|
||||
letterSpacing: "0px",
|
||||
fontWeight: 400,
|
||||
color: theme.palette.text.primary,
|
||||
},
|
||||
}));
|
||||
}));
|
||||
|
||||
65
src/components/common/CopyLinkButton.tsx
Normal file
65
src/components/common/CopyLinkButton.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import ShareIcon from "@mui/icons-material/Share";
|
||||
import {
|
||||
Box,
|
||||
ButtonBase,
|
||||
Tooltip,
|
||||
tooltipClasses,
|
||||
TooltipProps,
|
||||
} from "@mui/material";
|
||||
import { styled } from "@mui/system";
|
||||
|
||||
import { useDispatch } from "react-redux";
|
||||
import { setNotification } from "../../state/features/notificationsSlice.ts";
|
||||
|
||||
export interface CopyLinkButtonProps {
|
||||
link: string;
|
||||
tooltipTitle: string;
|
||||
}
|
||||
|
||||
export const TooltipLine = styled("div")(({ theme }) => ({
|
||||
fontSize: "18px",
|
||||
}));
|
||||
|
||||
const CustomWidthTooltipStyles = styled(
|
||||
({ className, ...props }: TooltipProps) => (
|
||||
<Tooltip {...props} classes={{ popper: className }} />
|
||||
)
|
||||
)({
|
||||
[`& .${tooltipClasses.tooltip}`]: {
|
||||
maxWidth: 600,
|
||||
},
|
||||
});
|
||||
|
||||
export const CustomTooltip = ({ title, ...props }: TooltipProps) => {
|
||||
if (typeof title === "string") title = <TooltipLine>{title}</TooltipLine>;
|
||||
|
||||
return <CustomWidthTooltipStyles title={title} {...props} />;
|
||||
};
|
||||
|
||||
export const CopyLinkButton = ({ link, tooltipTitle }: CopyLinkButtonProps) => {
|
||||
const dispatch = useDispatch();
|
||||
return (
|
||||
<CustomTooltip title={tooltipTitle} placement={"top"} arrow>
|
||||
<Box
|
||||
sx={{
|
||||
cursor: "pointer",
|
||||
}}
|
||||
>
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(link).then(() => {
|
||||
dispatch(
|
||||
setNotification({
|
||||
msg: "Copied to clipboard!",
|
||||
alertType: "success",
|
||||
})
|
||||
);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<ShareIcon />
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
</CustomTooltip>
|
||||
);
|
||||
};
|
||||
@@ -1,3 +1,13 @@
|
||||
export const minPriceSuperlike = 10;
|
||||
export const titleFormatter = /[^a-zA-Z0-9\s-_!?()&'",.;:|—~@#$%^*+=<>]/g;
|
||||
export const titleFormatterOnSave = /[^a-zA-Z0-9\s-_!()&',.;—~@#$%^+=]/g;
|
||||
export const titleFormatterOnSave = /[^a-zA-Z0-9\s-_!()&',.;—~@#$%^+=]/g;
|
||||
|
||||
export const fileMaxSize = 2147; // Size in Megabytes (decimal)
|
||||
export const maxSize = fileMaxSize * 1024 * 1024;
|
||||
|
||||
export const fontSizeExSmall = "70%";
|
||||
export const fontSizeSmall = "80%";
|
||||
export const fontSizeMedium = "100%";
|
||||
export const fontSizeLarge = "120%";
|
||||
export const fontSizeExLarge = "150%";
|
||||
export const maxCommentLength = 10_000;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React, { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { CopyLinkButton } from "../../components/common/CopyLinkButton.tsx";
|
||||
import { fontSizeMedium } from "../../constants/Misc.ts";
|
||||
import { setIsLoadingGlobal } from "../../state/features/globalSlice";
|
||||
import { Avatar, Box, Typography, useTheme } from "@mui/material";
|
||||
import { RootState } from "../../state/store";
|
||||
@@ -309,7 +311,7 @@ export const FileContent = () => {
|
||||
});
|
||||
return categoryDisplay;
|
||||
}
|
||||
return "no videodata";
|
||||
return "No file data";
|
||||
}, [fileData]);
|
||||
|
||||
return (
|
||||
@@ -404,16 +406,21 @@ export const FileContent = () => {
|
||||
</StyledCardHeaderComment>
|
||||
</Box>
|
||||
<Spacer height="15px" />
|
||||
<Box>
|
||||
<Typography
|
||||
sx={{
|
||||
fontWeight: "bold",
|
||||
fontSize: "16px",
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
{categoriesDisplay}
|
||||
</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "10px",
|
||||
fontWeight: "bold",
|
||||
fontSize: fontSizeMedium,
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
{categoriesDisplay}
|
||||
<CopyLinkButton
|
||||
link={`qortal://APP/Q-Share/share/${encodeURIComponent(fileData?.user)}/${encodeURIComponent(fileData?.id)}`}
|
||||
tooltipTitle={`Copy page link`}
|
||||
/>
|
||||
</Box>
|
||||
<Spacer height="15px" />
|
||||
<Box
|
||||
|
||||
@@ -16,7 +16,6 @@ import { VideoPlayerGlobal } from "../components/common/VideoPlayerGlobal";
|
||||
import { Rnd } from "react-rnd";
|
||||
import { RequestQueue } from "../utils/queue";
|
||||
import { EditFile } from "../components/EditFile/EditFile.tsx";
|
||||
import { EditPlaylist } from "../components/EditPlaylist/EditPlaylist";
|
||||
import ConsentModal from "../components/common/ConsentModal";
|
||||
import { useIframe } from "../hooks/useIframe.tsx";
|
||||
|
||||
@@ -30,7 +29,7 @@ let timer: number | null = null;
|
||||
export const queue = new RequestQueue();
|
||||
|
||||
const GlobalWrapper: React.FC<Props> = ({ children, setTheme }) => {
|
||||
useIframe()
|
||||
useIframe();
|
||||
const dispatch = useDispatch();
|
||||
const isDragging = useRef(false);
|
||||
const [userAvatar, setUserAvatar] = useState<string>("");
|
||||
@@ -141,7 +140,7 @@ const GlobalWrapper: React.FC<Props> = ({ children, setTheme }) => {
|
||||
authenticate={askForAccountInformation}
|
||||
/>
|
||||
<EditFile />
|
||||
<EditPlaylist />
|
||||
|
||||
<Rnd
|
||||
onDragStart={onDragStart}
|
||||
onDragStop={onDragStop}
|
||||
|
||||
Reference in New Issue
Block a user