Skip to content

Commit

Permalink
feat: forum redirect and styling (#472)
Browse files Browse the repository at this point in the history
* feat: adding redirect logic for success and minor styling

* feat: dynamic sizing
  • Loading branch information
JasonNotJson authored Oct 4, 2023
1 parent 8cb48a4 commit 135d302
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 77 deletions.
4 changes: 2 additions & 2 deletions apps/forum/src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ const InnerApp = () => {
commentNotify={commentNotify}
/>
</div>
<div className="flex flex-col h-[calc(100vh-50px)] mt-[23px]">
<div className="flex flex-col h-fit md:mt-[23px]">
{/* <div className="basis-[calc(100vh-187px)] lg:basis-[80%] dark:text-dark-text1"> */}
<div className="flex justify-between pl-2 gap-4 h-[calc(100vh-143px)]">
<div className="flex justify-between pl-2 gap-4 h-[calc(100vh-100px)]">
<div className="flex flex-col w-1/5">
{/* <BreadCrumbs onTriggerFetch={handleTriggerFetch} /> */}
<div className="pl-2 lg:pl-10">
Expand Down
4 changes: 2 additions & 2 deletions apps/forum/src/components/Board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,10 @@ const Board = ({ triggerRefresh, setBoard }: any) => {

return (
// <div className="max-w-2/5 w-5/6 mx-auto h-full">
<div className="mx-auto px-2 h-full lg:w-5/6 max-w-[5/6] standard-style">
<div className="mx-auto px-2 h-full lg:w-5/6 max-w-[280px] sm:max-w-[900px] standard-style overflow-y-hidden">
<CreateThread onNewThread={handleNewThread} />
<div
className="overflow-auto h-[calc(100%-44px)] mt-4 md:mt-8 lg:mt-12"
className="overflow-auto h-[calc(100%-150px)] mt-4 md:mt-8 lg:mt-12"
id="scrollableDiv"
>
<InfiniteScroll
Expand Down
23 changes: 18 additions & 5 deletions apps/forum/src/components/CommentForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ChangeEvent, useEffect, useState } from "react";
import React, { ChangeEvent, useEffect, useState, useRef } from "react";
import { useParams } from "react-router-dom";
import API from "@aws-amplify/api";
import { SignInModal, getIdToken } from "wasedatime-ui";
Expand All @@ -23,6 +23,7 @@ const CommentForm: React.FC<CommentFormProps> = ({
const [comment, setComment] = useState("");
const { boardSlug, threadUuid } = useParams();
const { t } = useTranslation();
const textareaRef = useRef(null);

const handleFocusForm = async () => {
if (userToken?.length <= 0) {
Expand All @@ -38,12 +39,23 @@ const CommentForm: React.FC<CommentFormProps> = ({
}
};

const handleTextChange = (e: ChangeEvent<HTMLInputElement>) => {
const handleTextChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
const textArea = textareaRef.current!;
textArea.style.height = "auto";
textArea.style.height = `${textArea.scrollHeight}px`;
setComment(e.target.value);
};

const handleSubmit = async () => {
if (comment.length <= 0 || comment.length > 200) return;
if (comment.length <= 0) {
alert("Your comment cannot be empty.");
return;
}

if (comment.length > 200) {
alert("Your comment cannot exceed 200 characters.");
return;
}

let idToken = userToken;
if (idToken?.length <= 0) {
Expand Down Expand Up @@ -110,9 +122,10 @@ const CommentForm: React.FC<CommentFormProps> = ({
};

return (
<div className="flex justify-between">
<div className="flex justify-between items-center">
{/* <div>Posted at ${time}</div> */}
<input
<textarea
ref={textareaRef}
className="text-2xl text-light-text3 dark:text-dark-text1 w-full focus:text-light-text1 focus:ring border-2 mt-4 mb-2 rounded-lg px-4 py-2 standard-style"
placeholder="Write your comment here (no more than 200 character)"
value={comment}
Expand Down
152 changes: 92 additions & 60 deletions apps/forum/src/components/CreateThread.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import React, { ChangeEvent, useEffect, useState, Fragment } from "react";
import React, {
ChangeEvent,
useEffect,
useState,
Fragment,
useRef,
} from "react";
import { useParams } from "react-router-dom";
import API from "@aws-amplify/api";
import { CloseIcon } from "@app/components/icons/CloseIcon";
Expand All @@ -11,6 +17,7 @@ import ThreadType from "@app/types/thread";
import TagType from "@app/types/tag";
import ImageIcon from "@mui/icons-material/Image";
import threadPayload from "@app/types/threadPayload";
import AddPhotoAlternateIcon from "@mui/icons-material/AddPhotoAlternate";

interface CreateThreadProps {
onNewThread: (newThread: ThreadType) => void;
Expand All @@ -21,7 +28,6 @@ function classNames(...classes) {
}

const CreateThread = ({ onNewThread }: CreateThreadProps) => {
const [isExpanded, setIsExpanded] = useState(false);
const [expandSchool, setExpandSchool] = useState(false);
const [isSignInModalOpen, setSignInModalOpen] = useState(false);
const [userToken, setUserToken] = useState("");
Expand All @@ -34,14 +40,36 @@ const CreateThread = ({ onNewThread }: CreateThreadProps) => {
const [fileName, setFileName] = useState<string | null>(null);
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const [fileType, setFileType] = useState<string | null>(null);
const [isButtonDisabled, setIsButtonDisabled] = useState(true);
const [isExpanded, setIsExpanded] = useState(false);
const textareaRef = useRef(null);

// Tags and Group buttons might be best moved to their respective components but this is how I will leave it for now.
const { boardSlug } = useParams();
const { t } = useTranslation();

useEffect(() => {
const trimmedTextContent = textContent.trim();

const isInvalidToken = !userToken || userToken.length <= 0;
const isInvalidBoard = !selectedBoard;
const isInvalidTextContent =
!textContent ||
trimmedTextContent.length <= 0 ||
trimmedTextContent.length > 2000;
const isInvalidSchool = !selectedSchool;

// Enable button only if all conditions are false (i.e., all are valid)
setIsButtonDisabled(
isInvalidToken ||
isInvalidBoard ||
isInvalidTextContent ||
isInvalidSchool
);
}, [userToken, selectedBoard, textContent, selectedSchool]);

useEffect(() => {
setSelectedBoard(boardSlug || "");
setIsExpanded(false);
setExpandSchool(false);
}, [boardSlug]);

Expand All @@ -62,12 +90,10 @@ const CreateThread = ({ onNewThread }: CreateThreadProps) => {

const handleOpenForm = async () => {
if (userToken?.length > 0) {
setIsExpanded(true);
} else {
const idToken = await getIdToken();
if (idToken?.length > 0) {
setUserToken(idToken);
setIsExpanded(true);
} else {
setSignInModalOpen(true);
}
Expand All @@ -79,6 +105,9 @@ const CreateThread = ({ onNewThread }: CreateThreadProps) => {
};

const handleBodyChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
const textArea = textareaRef.current!;
textArea.style.height = "auto";
textArea.style.height = `${textArea.scrollHeight}px`;
setTextContent(e.target.value);
};

Expand Down Expand Up @@ -215,7 +244,7 @@ const CreateThread = ({ onNewThread }: CreateThreadProps) => {
? getTitleBySlug(slug)
: selectedBoard
? getTitleBySlug(selectedBoard)
: "What's the Topic?"}
: "Topic"}
</Menu.Button>
</div>

Expand Down Expand Up @@ -255,31 +284,34 @@ const CreateThread = ({ onNewThread }: CreateThreadProps) => {
);
};

return isExpanded ? (
<div className="relative">
<div className="border-4 text-start text-black dark:text-white bg-light-card1 dark:bg-dark-bgMain dark:text-dark-text1 dark:shadow-none p-2 border-light-main dark:border-dark-main rounded-lg">
<BoardDropdownMenu slug={boardSlug} />
{/* <textarea
placeholder={`Enter Title`}
className="border-b-2 overflow-y-hidden border-light-main dark:border-dark-main h-10 pl-2 pb-2 w-full hover:outline-0 focus:outline-0 standard-style"
value={titleContent}
onChange={handleTitleChange}
/> */}
<textarea
placeholder={`Anything interesting?`}
className=" h-50 pl-2 pb-28 pt-2 w-full hover:outline-0 focus:outline-0 standard-style text-3xl overflow-y-hidden"
value={textContent}
onChange={handleBodyChange}
/>
</div>
<button
className="absolute top-0 right-2 m-1 p-1 hover:text-light-main cursor-pointer"
onClick={() => setIsExpanded(false)}
>
<CloseIcon />
</button>
<div className="absolute bottom-0 left-2 w-full flex mb-3 mt-3 text-sm justify-between">
<div className="my-auto flex flex-row gap-x-2">
return (
<div>
<div className="relative">
<div className="border-t-4 border-l-4 border-r-4 p-2 text-start text-black dark:text-white bg-light-card1 dark:bg-dark-bgMain dark:text-dark-text1 dark:shadow-none p-2 border-light-main dark:border-dark-main rounded-t-lg flex justify-between items-start relative">
{/* Added 'relative' to the parent div's class list */}

<textarea
placeholder={`Anything interesting?`}
className="h-50 pl-2 pt-2 pb-20 w-full hover:outline-0 focus:outline-0 standard-style text-3xl "
value={textContent}
onChange={handleBodyChange}
onFocus={handleOpenForm}
ref={textareaRef}
/>

<button
className={`absolute bottom-0 right-0 border m-4 px-4 py-2 rounded-lg text-3xl z-10 ${
isButtonDisabled
? "bg-gray-400 text-gray-700 hover:bg-gray-400 cursor-not-allowed"
: "border-light-main text-white bg-light-lighter hover:bg-light-darker"
}`}
onClick={isButtonDisabled ? () => {} : handleSubmit}
disabled={isButtonDisabled}
>
Post
</button>
</div>
<div className=" bottom-0 border-l-4 border-r-4 border-b-4 rounded-b-lg border-light-main dark:border-dark-main border-2 left-2 w-full flex text-sm justify-between items-center">
{/* {selectedBoard && (
<Menu as="div" className="relative inline-block text-left">
<div>
Expand Down Expand Up @@ -326,25 +358,30 @@ const CreateThread = ({ onNewThread }: CreateThreadProps) => {
</Transition>
</Menu>
)} */}
<button
className="inline-flex w-full justify-center gap-x-1.5 rounded-md px-3 py-2 text-sm font-semibold shadow-sm ring-1 ring-inset ring-gray-300 standard-style-hover"
onClick={() => setExpandSchool(!expandSchool)}
>
{expandSchool ? (
<SchoolFilterForm
isOpen={expandSchool}
setOpen={setExpandSchool}
setSchool={setSelectedSchool}
/>
) : null}
<p>{selectedSchool ? selectedSchool : "School"}</p>
</button>
<div className="uploader">
<div className="w-1/3 p-2 flex justify-center items-center">
<BoardDropdownMenu slug={boardSlug} />
</div>
<div className="w-1/3 p-2 flex justify-center items-center">
<button
className="inline-flex gap-x-1.5 rounded-md bg-white px-3 py-2 text-2xl font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 standard-style-hover"
onClick={() => setExpandSchool(!expandSchool)}
>
{expandSchool ? (
<SchoolFilterForm
isOpen={expandSchool}
setOpen={setExpandSchool}
setSchool={setSelectedSchool}
/>
) : null}
<p>{selectedSchool ? selectedSchool : "School"}</p>
</button>
</div>
<div className="uploader flex justify-center items-center w-1/3 p-2">
<label htmlFor="imageUpload" className="cursor-pointer">
{fileName ? (
<span>{fileName}</span>
) : (
<ImageIcon fontSize="large" />
<AddPhotoAlternateIcon style={{ fontSize: "40px" }} />
)}
</label>
<input
Expand All @@ -356,21 +393,8 @@ const CreateThread = ({ onNewThread }: CreateThreadProps) => {
/>
</div>
</div>
<button
className="border-light-main border mx-4 px-4 py-1 rounded-lg text-white bg-light-lighter hover:bg-light-darker text-3xl"
onClick={handleSubmit}
>
Post
</button>
</div>
</div>
) : (
<div>
<div className="cursor-pointer" onClick={handleOpenForm}>
<h1 className="border-4 p-2 rounded-lg border-light-main">
Anything interesting?
</h1>
</div>

<SignInModal
isModalOpen={isSignInModalOpen}
closeModal={() => setSignInModalOpen(false)}
Expand All @@ -381,3 +405,11 @@ const CreateThread = ({ onNewThread }: CreateThreadProps) => {
};

export default CreateThread;
{
/* <textarea
placeholder={`Enter Title`}
className="border-b-2 overflow-y-hidden border-light-main dark:border-dark-main h-10 pl-2 pb-2 w-full hover:outline-0 focus:outline-0 standard-style"
value={titleContent}
onChange={handleTitleChange}
/> */
}
4 changes: 2 additions & 2 deletions apps/forum/src/components/Thread.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ const Thread = () => {
}, [threadUuid, boardSlug]);

const handleNewComment = (newComment: CommentType) => {
setComments((prevComments) => [newComment, ...prevComments]);
setComments((prevComments) => [...prevComments, newComment]);
};

return (
<div className="border-2 mt-12 mx-1 md:mx-auto rounded-xl shadow-lg py-6 h-fit px-4 standard-style max-w-[290px] lg:max-w-[900px]">
<div className="border-2 w-full md:w-5/6 mx-auto rounded-xl shadow-lg py-6 px-4 standard-style max-w-[290px] sm:max-w-[900px] overflow-y-auto h-fit">
{/* <CreateThread /> */}

<ThreadBlock isPreview={false} thread={thread} />
Expand Down
2 changes: 1 addition & 1 deletion apps/forum/src/components/ThreadBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ const ThreadBlock = ({ isPreview, fromRoot, thread, onDelete }: Props) => {
<img
src={thread.url}
alt="Thread Image"
className="block mx-auto p-4"
className="block mx-auto p-4 max-h-[calc(100vh-143px*2)]"
/>
) : null}
<h2
Expand Down
2 changes: 1 addition & 1 deletion apps/forum/src/root.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ ReactGA.initialize(import.meta.env.VITE_GA_ID, {});

export default function Root(props) {
return (
<section className="h-screen">
<section className="sm:h-screen h-[calc(100vh-50px)]">
<RecoilRoot>
<ThemeProvider>
<App />
Expand Down
7 changes: 3 additions & 4 deletions apps/root/src/components/user/RedirectPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,15 @@ const RedirectPage = () => {
if (window.location.search.includes("error_description")) {
await timeout(5000)
navigate("/")
} else {
await timeout(1000)
navigate("/")
}
}

redirectToHomeAfter5Sec().catch((err) => console.error(err))
}, [])

//! https://wasedatime.com/verify?error_description=Loginfail....

//! https://wasedatime.com/verify -> considered as success

return window.location.search.includes("error_description") ? (
<div className="mt-20 text-center">
<LoadingSpinner theme={theme} message={t("verify.failed.title")} />
Expand Down

0 comments on commit 135d302

Please sign in to comment.