Skip to content

Commit

Permalink
Shot detail page ...
Browse files Browse the repository at this point in the history
  • Loading branch information
JeremyG11 committed Feb 14, 2024
1 parent 0cba697 commit a2bf04c
Show file tree
Hide file tree
Showing 16 changed files with 159 additions and 78 deletions.
6 changes: 3 additions & 3 deletions components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { VscChromeClose } from "react-icons/vsc";
import { HiOutlineMenuAlt2 } from "react-icons/hi";

import Logo from "./shared/Logo";
import useMount from "@/hooks/mount";
import { Profile } from "@prisma/client";
import SearchBar from "./Home/SearchBar";
import { Button } from "./shared/Button";
Expand All @@ -17,14 +18,13 @@ interface NavbarProps {
export default function Navbar({ profile }: NavbarProps) {
const [state, setState] = useState(false);
const router = useRouter();
// Replace # paths with your paths
useEffect(() => {
document.onclick = (e) => {
const target = e.target;
// if (!target.closest(".menu-btn")) setState(false);
};
}, []);

const mount = useMount();
if (!mount) return null;
return (
<nav className={`bg-white md:text-sm p-4 `}>
<div className="md:gap-x-14 justify-between items-center max-w-screen-xl md:mx-auto flex ">
Expand Down
2 changes: 1 addition & 1 deletion components/Profile/Blocks/GalleryBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export const MiniGalleryUploader = ({
const selectedFile = e.target.files[0];
setFile(selectedFile);

const fileData = { file: selectedFile, type: "mediaType" };
const fileData = { file: selectedFile, type: "mediaType", altText: "" };

onOpenBlock("gallery");
if (boardData?.gallery) {
Expand Down
15 changes: 10 additions & 5 deletions components/Profile/Blocks/ImageBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,16 @@ export const ImageBlock = () => {
</div>
<div>
<MediaUpload mediaType="image" mediaSrcUrl={mediaSrcUrl} />
<AltText
label="Alt Text"
placeholder="Enter Text..."
className="block w-full placeholder-gray-400/70 dark:placeholder-gray-500 rounded-lg border border-gray-200 bg-white px-5 py-4 text-gray-700 focus:border-pink-300 focus:outline-none focus:ring focus:ring-pink-200 focus:ring-opacity-40"
/>
{boardData.image?.files?.map((file, index) => (
<AltText
key={index}
blockType="image"
fileIndex={index}
label={`Alt Text ${index + 1}`}
placeholder="Enter Text..."
className="block w-full placeholder-gray-400/70 dark:placeholder-gray-500 rounded-lg border border-gray-200 bg-white px-5 py-4 text-gray-700 focus:border-pink-300 focus:outline-none focus:ring focus:ring-pink-200 focus:ring-opacity-40"
/>
))}
<AdjustLayout />
</div>
</div>
Expand Down
20 changes: 12 additions & 8 deletions components/Profile/Blocks/VideoBlock.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use client";
import Image from "next/image";
import { useBlock } from "@/hooks/zustandStore";
import AltText from "../../shared/AltText";
import { useBlock } from "@/hooks/zustandStore";
import MediaUpload from "../../shared/MediaUpload";
import AdjustLayout from "../../shared/AdjustLayout";
import { createFileUrl } from "@/libs/utils/createFileUrl";
Expand All @@ -13,7 +12,7 @@ export const VideoBlock = () => {
if (Array.isArray(boardData?.video)) {
mediaSrcUrl = boardData?.video[0];
} else if (boardData?.video && "files" in boardData?.video) {
mediaSrcUrl = createFileUrl(boardData.video?.files[0].file);
mediaSrcUrl = createFileUrl(boardData.video?.files[0]?.file);
}

return (
Expand Down Expand Up @@ -41,11 +40,16 @@ export const VideoBlock = () => {
</div>
<div>
<MediaUpload mediaType="video" mediaSrcUrl={mediaSrcUrl} />
<AltText
label="Alt Text"
placeholder="Enter Text..."
className="block w-full placeholder-gray-400/70 dark:placeholder-gray-500 rounded-lg border border-gray-200 bg-white px-5 py-4 text-gray-700 focus:border-pink-300 focus:outline-none focus:ring focus:ring-pink-200 focus:ring-opacity-40"
/>
{boardData.video?.files?.map((file, index) => (
<AltText
key={index}
blockType="video"
fileIndex={index}
label={`Alt Text ${index + 1}`}
placeholder="Enter Text..."
className="block w-full placeholder-gray-400/70 dark:placeholder-gray-500 rounded-lg border border-gray-200 bg-white px-5 py-4 text-gray-700 focus:border-pink-300 focus:outline-none focus:ring focus:ring-pink-200 focus:ring-opacity-40"
/>
))}
<AdjustLayout />
</div>
</div>
Expand Down
26 changes: 4 additions & 22 deletions components/Profile/FileUploader.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,22 @@
"use client";
import Image from "next/image";
import { FileWithPath } from "@uploadthing/react";
import { FileData, useBlock } from "@/hooks/zustandStore";
import { useDropzone } from "@uploadthing/react/hooks";
import imageIcon from "@/public/images/shotUploadIcon.png";
import { generateClientDropzoneAccept } from "uploadthing/client";
import React, {
ChangeEvent,
Dispatch,
SetStateAction,
useCallback,
} from "react";
import React, { ChangeEvent, Dispatch, SetStateAction } from "react";

interface FileUploaderProps {
onFilesChange: (files: File[]) => void;
setFiles: Dispatch<SetStateAction<File[]>>;
}

const FileUploader = ({ onFilesChange, setFiles }: FileUploaderProps) => {
const FileUploader = ({ onFilesChange }: FileUploaderProps) => {
const { onOpenBlock, updateFiles, setDrawerOpen } = useBlock();

const createFileData = (file: File): FileData => {
const fileType = file.type.split("/")[0];
return { file: file, type: fileType };
return { file: file, type: fileType, altText: "" };
};

const onDrop = useCallback((acceptedFiles: FileWithPath[]) => {
setFiles(acceptedFiles);
}, []);

const { getRootProps, getInputProps } = useDropzone({
onDrop,
accept: "image/*" ? generateClientDropzoneAccept(["image/*"]) : undefined,
});

const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files.length > 0) {
const selectedFiles = Array.from(e.target.files);
Expand All @@ -56,7 +39,7 @@ const FileUploader = ({ onFilesChange, setFiles }: FileUploaderProps) => {
}
};
return (
<div {...getRootProps()} className="relative w-full h-full">
<div className="relative w-full h-full">
<label
htmlFor="dropzone-file"
className="relative p-3 max-w-5xl mx-auto flex flex-col justify-center w-full h-screen border-2 border-gray-300 border-dashed rounded-lg cursor-pointer"
Expand Down Expand Up @@ -88,7 +71,6 @@ const FileUploader = ({ onFilesChange, setFiles }: FileUploaderProps) => {
</div>

<input
{...getInputProps()}
id="dropzone-file"
type="file"
className="hidden"
Expand Down
42 changes: 22 additions & 20 deletions components/Profile/PublishShotModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,30 @@ import { useForm } from "react-hook-form";
import { Button } from "../shared/Button";
import TagsInput from "../shared/InputTag";
import { useBlock } from "@/hooks/zustandStore";
import { uploadFiles } from "@/libs/uploadthing";
import { publishShot } from "@/libs/actions/shot.actions";
import { uploadFilesAndReturnUrls } from "@/libs/utils/uploadFilesAndReturnUrls";
import { TBoardData } from "@/libs/definitions";

export function PublishShotModal() {
const { isOpen, type, onClose, data } = useModal();
const { boardData, resetBoardData } = useBlock();
const router = useRouter();

const isPublishShotModal = isOpen && type === "publishShotModal";
type Uploader = "imageUploader" | "videoUploader" | "galleryUploader";

const uploadFilesAndReturnUrls = async (
uploader: Uploader,
filesData: any
) => {
const files = filesData.map((fileData: any) => fileData.file);
const uploadedFiles = await uploadFiles(uploader, { files });
return uploadedFiles.map((file: any) => file.url);
const { reset, handleSubmit, formState } = useForm();
const { isSubmitting, isSubmitSuccessful } = formState;

const extractAltTexts = (boardData: TBoardData, fileType: string) => {
return boardData[fileType]?.files?.map((file) => file.altText);
};

const { reset, register, handleSubmit, formState } = useForm();
const { isSubmitting, isSubmitSuccessful } = formState;
const onSubmit = async () => {
const id = data?.id;
if (id) {
try {
let galleryImageUrls: string[] = [];
let filesUrls: string[] = [];

if (boardData["gallery"]?.files) {
galleryImageUrls = await uploadFilesAndReturnUrls(
"galleryUploader",
Expand All @@ -63,14 +58,21 @@ export function PublishShotModal() {
filesUrls.push(videoUrl);
}

const res = await publishShot(id, filesUrls, galleryImageUrls);
if (res?.success) {
router.refresh();
router.push(`/shots/${id}`);
onClose();
reset();
resetBoardData();
}
const imageAltTexts = extractAltTexts(boardData, "image");
const videoAltTexts = extractAltTexts(boardData, "video");
const galleryAltTexts = extractAltTexts(boardData, "gallery");

const res = await publishShot(id, filesUrls, galleryImageUrls, {
video: videoAltTexts,
image: imageAltTexts,
gallery: galleryAltTexts,
});

router.refresh();
router.push(`/shots/${id}`);
onClose();
reset();
resetBoardData();
} catch (error: any) {
console.log("Error", error.message);
}
Expand Down
2 changes: 1 addition & 1 deletion components/Profile/ShotUploadForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export default function ShotUploadForm() {
placeholder=" Give me a name"
{...register("title", {
required: true,
maxLength: 20,
maxLength: 32,
})}
onChange={(e) => setTitle(e.target.value)}
className="mx-auto outline-none placeholder:text-gray-400"
Expand Down
28 changes: 25 additions & 3 deletions components/shared/AltText.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
import React from "react";
import React, { useState, useEffect } from "react";
import { BlockType, useBlock } from "@/hooks/zustandStore";

interface AltTextProps {
label?: string;
className: string;
placeholder: string;
onClick?: (event: MouseEvent) => void;
blockType: BlockType;
fileIndex: number;
}

export default function AltText({
label,
className,
placeholder,
onClick,
blockType,
fileIndex,
}: AltTextProps) {
const { boardData, updateAltText } = useBlock();
const [altText, setAltText] = useState("");

useEffect(() => {
const fileData = boardData[blockType]?.files[fileIndex];
if (fileData) {
setAltText(fileData.altText);
}
}, [boardData, blockType, fileIndex]);

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const newAltText = event.target.value;
setAltText(newAltText);
updateAltText(blockType, fileIndex, newAltText);
};

return (
<div>
<label htmlFor="file" className="block font-normal mt-4 py-1.5 pt-4">
Expand All @@ -22,6 +42,8 @@ export default function AltText({
type="text"
placeholder={`${placeholder}`}
className={`${className}`}
value={altText}
onChange={handleChange}
/>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion components/shared/MediaUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default function MediaUpload({
const selectedFile = e.target.files[0];
setFile(selectedFile);

const fileData = { file: selectedFile, type: mediaType };
const fileData = { file: selectedFile, type: mediaType, altText: "" };

if (mediaType === "image") {
onOpenBlock("image");
Expand Down
29 changes: 17 additions & 12 deletions components/shared/ShotDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ interface ShotDetailPageProps {
}

export default function ShotDetailPage({ shot }: ShotDetailPageProps) {
const [activeLink, setActiveLink] = useState<string | null>(null);
const [toggleNav, setToggleNav] = useState(false);

const [scrollActive, setScrollActive] = useState(false);

useEffect(() => {
Expand All @@ -33,7 +30,7 @@ export default function ShotDetailPage({ shot }: ShotDetailPageProps) {
window.removeEventListener("scroll", handleScroll);
};
}, []);

console.log(shot.files);
return (
<section className="bg-white ">
<nav
Expand Down Expand Up @@ -74,29 +71,37 @@ export default function ShotDetailPage({ shot }: ShotDetailPageProps) {
</div>
</nav>
<div className="container flex flex-col items-center p-4 mx-auto xl:flex-row lg:max-w-5xl ">
<div className="relative w-full h-96 md:h-screen first-letter:flex justify-center overflow-hidden rounded-lg">
{shot.files.map((file) => {
<div className="bg-red-400">
{shot.files.map((fileUrl, index) => {
return (
<>
{file.endsWith(".mp4") ? (
<div key={index}>
{fileUrl.endsWith(".mp4") ? (
<video
key={index}
className="object-cover w-full h-full"
autoPlay
loop
muted
onError={(e) => {
console.error(`Error loading video: ${e}`);
}}
>
<source src={file} type="video/mp4" />
<source src={fileUrl} type="video/mp4" />
Your browser does not support the video tag.
</video>
) : (
<Image
className="h-80 w-80 sm:w-[28rem] sm:h-[28rem] flex-shrink-0 object-cover "
src={shot.files[0]}
key={index}
className=" sm:w-[28rem] sm:h-[28rem] flex-shrink-0 object-cover h-full w-full"
src={fileUrl}
alt=""
onError={(e) => {
console.error(`Error loading image: ${e}`);
}}
fill
/>
)}
</>
</div>
);
})}
</div>
Expand Down
15 changes: 15 additions & 0 deletions hooks/mount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"use client";

import { useEffect, useState } from "react";

function useMount() {
const [mount, setMount] = useState(false);

useEffect(() => {
setMount(true);
}, [mount]);

return mount;
}

export default useMount;
Loading

0 comments on commit a2bf04c

Please sign in to comment.