Skip to content
This repository has been archived by the owner on Oct 29, 2024. It is now read-only.

Commit

Permalink
fix bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
Thinh Nguyen D committed Oct 4, 2024
1 parent e0a425e commit d96957d
Show file tree
Hide file tree
Showing 11 changed files with 315 additions and 226 deletions.
3 changes: 3 additions & 0 deletions src/components/DisplayVideo/DisplayVideo.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.main_video {
object-fit: cover;
}
3 changes: 2 additions & 1 deletion src/components/DisplayVideo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import React from "react";
import { Player } from "video-react";

import "video-react/dist/video-react.css";
import "./DisplayVideo.scss";

const DisplayVideo = ({ videoSrc }) => {
return (
<div className="display_video">
<Player playsInline src={videoSrc} width={180} height={20} />
<Player className="main_video" playsInline src={videoSrc} />
</div>
);
};
Expand Down
35 changes: 14 additions & 21 deletions src/components/HeroCard/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import React, { useState } from "react";
import React from "react";
import "./HeroCard.scss";

import {
Box,
Button,
Card,
CardContent,
CardMedia,
Typography,
} from "@mui/material";
import { Box, Button, Card, CardContent, Typography } from "@mui/material";

import { useNavigate } from "react-router-dom";

Expand All @@ -17,7 +10,7 @@ import useAuth from "../../hooks/useAuth";
import DisplayVideo from "../DisplayVideo";

function HeroCard({ video }) {
const [showActionButton, setShowActionButton] = useState(false);
const { isAuthenticated, user } = useAuth();

const navigate = useNavigate();

Expand All @@ -33,8 +26,8 @@ function HeroCard({ video }) {
boxShadow: "none",
}}
>
<div style={{ width: "100%", marginTop: "20px" }}>
<DisplayVideo videoSrc={video.videoUrl} />
<div style={{ width: "100%", maxWidth: "720px" }}>
<DisplayVideo videoSrc={video?.videoUrl} />
</div>

<div
Expand All @@ -47,37 +40,37 @@ function HeroCard({ video }) {
<CardContent height={"100%"} sx={{ p: 0 }}>
<Box mb={2}>
<Typography variant="h5" sx={{ fontWeight: 700 }}>
{video.title}
{video?.title}
</Typography>
<Typography variant="h6">
{video.userName.firstName} {video.userName.lastName}
{video?.userName.firstName} {video?.userName.lastName}
</Typography>
</Box>
<Box>
<Box className="myVideoInfo_box">
<h4>Material</h4>
{video.material.map((mat) => (
<p>{mat}</p>
{video?.material.map((mat, index) => (
<p key={index}>{mat}</p>
))}
</Box>
<Box className="myVideoInfo_box">
<h4>Tool</h4>
{video.tool.map((tol) => (
<p>{tol}</p>
{video?.tool.map((tol, index) => (
<p key={index}>{tol}</p>
))}
</Box>
<Box className="myVideoInfo_box">
<h4>Difficulty</h4>
<p>{video.difficulty}</p>
<p>{video?.difficulty}</p>
</Box>
<Box className="myVideoInfo_box">
<h4>Duration</h4>
<p>{video.duration}</p>
<p>{video?.duration}</p>
</Box>
</Box>
</CardContent>

{showActionButton && (
{isAuthenticated && user._id === video.user_id && (
<div className="actionVideo_btn">
<Button
size="small"
Expand Down
2 changes: 1 addition & 1 deletion src/features/User/userSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const slice = createSlice({
state.isLoading = false;
state.error = null;
state.updateUserInfo = action.payload;
toast.success("Update profile successfully");
},
},
});
Expand All @@ -41,7 +42,6 @@ export const updateUserInfo =
}
);
dispatch(slice.actions.updateUserInfoSuccess(response.data));
toast.success("Update profile successfully");
} catch (error) {
dispatch(slice.actions.hasError(error.message));
toast.error(error.message);
Expand Down
40 changes: 40 additions & 0 deletions src/features/Video/EditVideo/EditVideo.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.uploadVideo_container {
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;

.uploadField_container {
display: flex;
width: 100%;
justify-content: center;
align-items: center;
.uploadField_box {
width: 50%;
padding: 10px;
border: 1px dashed black;
border-radius: 10px;

.icon_upload {
margin-bottom: 4px;
cursor: pointer;
width: 50px;
height: 50px;
&:hover {
scale: 1.1;
}
}

h5,
p {
text-align: center;
}
}
}

.display_video {
width: 100%;
margin-top: 20px;
}
}
213 changes: 213 additions & 0 deletions src/features/Video/EditVideo/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import React, { useState } from "react";
import "./EditVideo.scss";

import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as Yup from "yup";
import useAuth from "../../../hooks/useAuth";

import {
CATEGORY_OPTION,
COLLECTION_OPTION,
DIFFICULTY_OPTION,
DURATION_OPTION,
} from "../../../constants/list.constants";

import { FormProvider, FSelect, FTextField } from "../../../components/Form";
import { LoadingButton } from "@mui/lab";
import { cloudinaryVideoUpload } from "../../../ultis/cloudinary";
import { useDispatch, useSelector } from "react-redux";
import ToolsMultipleSelect from "../../../components/ToolsMulticheck";
import MaterialMultipleSelect from "../../../components/MaterialMulticheck";
import UploadNewVideo from "../UploadVideo/UploadNewVideo";
import { createVideo } from "../videoSlice";
import { useNavigate } from "react-router-dom";
import PATH_NAME from "../../../constants/pathName.constants";

const editVideoSchema = Yup.object().shape({
title: Yup.string().required("Title is required"),
category: Yup.string().required("Category is required"),
collection: Yup.string().required("Collection is required"),
difficulty: Yup.string().required("Difficulty is required"),
duration: Yup.string().required("Duration is required"),
material: Yup.array().min(1, "Material is required"),
tool: Yup.array().min(1, "Material is required"),
videoUrl: Yup.string().required("Video is required"),
});

const EditVideo = ({ initialData }) => {
const { user } = useAuth();
const navigate = useNavigate();

const { isLoading } = useSelector((state) => state.video);

const [videoSrc, setVideoSrc] = useState(initialData?.videoUrl || "");

const defaultValues = {
title: "",
category: "",
collection: "",
description: "",
difficulty: "",
duration: "",
material: [],
tool: [],
videoUrl: "",
videoFile: null,
...initialData,
};

const methods = useForm({
resolver: yupResolver(editVideoSchema),
defaultValues,
});

const {
handleSubmit,
formState: { errors, isSubmitting },
} = methods;

const dispatch = useDispatch();

const onSubmit = async (data) => {
let urlVideoFromCloudy = "";
if (data.videoFile) {
urlVideoFromCloudy = await handleUploadVideo(data.videoFile);
}
const formDataSubmit = {
...data,
videoUrl: urlVideoFromCloudy ? urlVideoFromCloudy : data.videoUrl,
};
delete formDataSubmit.videoFile;
dispatch(createVideo({ ...formDataSubmit, user_id: user._id })).then(
(response) => {
if (response.success) {
navigate(PATH_NAME.PROFILE);
}
}
);
};

const handleUploadVideo = async (fileVideo) => {
const response = await cloudinaryVideoUpload(fileVideo);

if (response.success) {
return response.videoUrl;
}
};

return (
<FormProvider
methods={methods}
onSubmit={handleSubmit(onSubmit)}
sx={{ display: "flex" }}
>
<div className="uploadVideo_container">
<UploadNewVideo videoSrc={videoSrc} setVideoSrc={setVideoSrc} />
<p
style={{
color: "#d32f2f",
fontSize: "0.75rem",
fontWeight: 400,
margin: "4px 14px 0 14px",
}}
>
{errors?.videoUrl?.message}
</p>
<div style={{ width: "100%" }}>
<h4>Title</h4>
<FTextField
name="title"
placeholder={"Enter your title video"}
sx={{ maxWidth: "876px" }}
/>
</div>

<div style={{ width: "100%" }}>
<h4>Description</h4>
<FTextField
sx={{ maxWidth: "876px" }}
name="description"
multiline
rows={4}
placeholder={"Tell your viewers about your video..."}
/>
</div>

<div
className="option_list"
style={{ maxWidth: "876px", width: "100%" }}
>
<h4>Duration</h4>
<FSelect name="duration" sx={{ maxWidth: "876px" }}>
{DURATION_OPTION.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</FSelect>

<h4>Difficulty</h4>
<FSelect name="difficulty" sx={{ maxWidth: "876px" }}>
{DIFFICULTY_OPTION.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</FSelect>

<h4>Material</h4>
<MaterialMultipleSelect name="material" sx={{ maxWidth: "876px" }} />

<h4>Tools</h4>
<ToolsMultipleSelect name="tool" sx={{ maxWidth: "876px" }} />

<h4>Category</h4>
<FSelect name="category" sx={{ maxWidth: "876px" }}>
{CATEGORY_OPTION.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</FSelect>

<h4>Collection</h4>
<FSelect name="collection" sx={{ maxWidth: "876px" }}>
{COLLECTION_OPTION.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</FSelect>
</div>

<div
width="100%"
style={{
marginTop: "30px",
maxWidth: "876px",
width: "100%",
display: "flex",
justifyContent: "flex-end",
}}
>
<LoadingButton
fullWidth
size="large"
type="submit"
variant="contained"
loading={isSubmitting || isLoading}
sx={{
maxWidth: "200px",
fontWeight: 700,
}}
>
Publish
</LoadingButton>
</div>
</div>
</FormProvider>
);
};

export default EditVideo;
1 change: 0 additions & 1 deletion src/features/Video/MyVideoList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ function MyVideoList({ userId }) {
const dispatch = useDispatch();

const { videos } = useSelector((state) => state.video);
console.log("🚀 Puritin ~ MyVideoList ~ videos:", videos);

useEffect(() => {
userId && dispatch(getVideo({ userId }));
Expand Down
3 changes: 0 additions & 3 deletions src/features/Video/UploadVideo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,9 @@ const UploadVideo = ({ initialData }) => {
formState: { errors, isSubmitting },
} = methods;

console.log("🚀 Puritin ~ UploadVideo ~ errors:", errors);

const dispatch = useDispatch();

const onSubmit = async (data) => {
console.log("🚀 Puritin ~ onSubmit ~ data:", data);
let urlVideoFromCloudy = "";
if (data.videoFile) {
urlVideoFromCloudy = await handleUploadVideo(data.videoFile);
Expand Down
Loading

0 comments on commit d96957d

Please sign in to comment.