Skip to content

Commit

Permalink
Merge pull request #38 from staruth0/clean-ups
Browse files Browse the repository at this point in the history
reacions on testphase
  • Loading branch information
Fabrice-Mokfembam authored Feb 7, 2025
2 parents 1e4df2d + f59ad0e commit bb85191
Show file tree
Hide file tree
Showing 17 changed files with 390 additions and 261 deletions.
2 changes: 1 addition & 1 deletion src/components/atoms/Topbar/Topbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const Topbar: React.FC<TopbarProps> = ({ children }) => {
toggleSidebar();
};
return (
<div className="h-[120px] sm:h-[80px] transition-all duration-[.5s] ease-linear w-full sm:border-b-[1px] border-neutral-500 flex flex-col justify-center sm:px-5 sticky top-0 z-9999 backdrop-blur-md">
<div className="h-[120px] sm:h-[80px] transition-all duration-[.5s] ease-linear w-full sm:border-b-[1px] border-neutral-500 flex flex-col justify-center sm:px-5 sticky top-0 z-9999 bg-background">
<div className="hamburger-menu sticky top-0 p-4 sm:hidden ">
<FaBars size={24} className="cursor-pointer" onClick={handleToggleSidebar}/>
</div>
Expand Down
71 changes: 5 additions & 66 deletions src/components/molecules/Tabs/Tabs.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
import React, { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import {
heart,
sadface,
smile,
thumb,
clap,
} from "../../../assets/icons/index";

interface TabsProps {
tabs: { id: number | string; title: string }[];
tabs: { id: number | string; title: string }[]; // title is now only a string
activeTab: number | string;
setActiveTab: (tabId: number | string) => void;
scale: boolean;
scale?: boolean;
borderBottom?: boolean;
isReaction?: boolean;
}

const Tabs: React.FC<TabsProps> = ({
Expand All @@ -23,7 +15,6 @@ const Tabs: React.FC<TabsProps> = ({
setActiveTab,
scale,
borderBottom,
isReaction
}) => {
const [tabStyle, setTabStyle] = useState<React.CSSProperties>({});
const tabRef = useRef<HTMLDivElement>(null);
Expand All @@ -45,70 +36,19 @@ const Tabs: React.FC<TabsProps> = ({
setActiveTab(tabId);
};


const getIcon = (title: string) => {
switch (title) {
case "All":
return (
<div className="font-semibold text-[16px] space-x-1">
<span>{title}</span>
<span>56</span>
</div>
);
case "heart":
return (
<div className="flex items-center gap-1 font-semibold text-[16px]">
<img src={heart} alt="Heart" className="w-6 h-6" />
<span>10</span>
</div>
);
case "sadface":
return (
<div className="flex items-center gap-1 font-semibold text-[16px]">
<img src={sadface} alt="Sad Face" className="w-6 h-6" />
<span>5</span>
</div>
);
case "smile":
return (
<div className="flex items-center gap-1 font-semibold text-[16px]">
<img src={smile} alt="Smile" className="w-6 h-6" />
<span>15</span>
</div>
);
case "thumb":
return (
<div className="flex items-center gap-1 font-semibold text-[16px]">
<img src={thumb} alt="Thumb" className="w-6 h-6" />
<span>8</span>
</div>
);
case "clap":
return (
<div className="flex items-center gap-1 font-semibold text-[16px] ">
<img src={clap} alt="Clap" className="w-6 h-6" />
<span>12</span>
</div>
);
default:
return null;
}
};

return (
<div className="flex flex-col items-center backdrop-blur-sm">
{/* Tabs */}
<div
ref={tabRef}
className={`relative flex justify-between w-full ${
className={`relative flex justify-between w-full ${
borderBottom ? "border-b" : ""
}`}
>
{tabs.map((tab) => (
<span
key={tab.id}
id={`tab-${tab.id}`}
className={`px-2 py-2 cursor-pointer transition-all border-b-2 -mb-0 flex items-center ${
className={`px-2 py-2 cursor-pointer transition-all border-b-2 -mb-0 flex items-center ${
activeTab === tab.id
? `border-primary-400 text-neutral-50 ${
scale ? "scale-110" : ""
Expand All @@ -117,10 +57,9 @@ const Tabs: React.FC<TabsProps> = ({
}`}
onClick={() => handleTabClick(tab.id)}
>
{isReaction ? getIcon(tab.title) : t(`${tab.title}`)}
{t(tab.title)}
</span>
))}
{/* Tab slider */}
<div
className="absolute bottom-0 h-[2px] bg-primary-400 transition-all duration-300"
style={tabStyle}
Expand Down
2 changes: 1 addition & 1 deletion src/feature/Blog/components/BlogComponents/BlogImagery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface BlogImageryProps {

const BlogImagery: React.FC<BlogImageryProps> = ({ PostImages }) => {
return (
<div className="relative w-full max-w-[300px] md:max-w-[500px] lg:max-w-[700px] mx-auto z-0 transition-all duration-300 ">
<div className="relative w-full max-w-[300px] md:max-w-[500px] lg:max-w-[700px] mx-auto transition-all duration-300 ">
<Swiper
modules={[Navigation, Pagination]}
navigation
Expand Down
2 changes: 1 addition & 1 deletion src/feature/Blog/components/BlogComponents/BlogMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const BlogMessage: React.FC<BlogMessageProps> = ({ title, content }) => {

return (
<div className="blog-message">
<h2 className="text-xl font-semibold mb-2">{title}</h2>
<div className="text-[15px] font-semibold mb-2">{title}</div>
<p
className={`text-neutral-50 text-[14px] transition-all duration-300 ${
isExpanded ? "line-clamp-none" : "line-clamp-3"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const BlogReactionSession: React.FC<BlogReactionSessionProps> = ({message,isComm

return (
<div>
<div className="blog-reaction-session border-t border-neutral-500 flex gap-4">
<div className="blog-reaction-session border-t border-neutral-500 flex gap-4 ">
<button
onMouseEnter={() => setModalOpen(true)}
onClick={() => setModalOpen(true)}
Expand Down
22 changes: 14 additions & 8 deletions src/feature/Blog/components/BlogComponents/BlogReactionStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@ import React, { useState } from "react";
import { hand5, heart, thumb } from "../../../../assets/icons";
import { timeAgo } from "../../../../utils/dateFormater";
import ReactionsPopup from "../../../Interactions/components/ReactionsPopup";
import { useGetCommentsByArticleId } from "../../../Comments/hooks";
import { useGetArticleReactions } from "../../../Interactions/hooks";

interface BlogReactionStatsProps {
date: string;
toggleCommentSection: () => void;
article_id: string;
}

const BlogReactionStats: React.FC<BlogReactionStatsProps> = ({ date, toggleCommentSection }) => {
const BlogReactionStats: React.FC<BlogReactionStatsProps> = ({ date, toggleCommentSection,article_id }) => {
const [showReactions, setShowReactions] = useState(false);

const { data: articleComments } = useGetCommentsByArticleId(article_id)
const {data: allReactions} = useGetArticleReactions(article_id);

const handlecloseReactionPopup = () => {
setShowReactions(false);
}
Expand All @@ -25,30 +31,30 @@ const BlogReactionStats: React.FC<BlogReactionStatsProps> = ({ date, toggleComme
<img
src={heart}
alt="heart"
className="w-5 h-5 rounded-full shadow-md transform transition-transform relative z-10 -ml-1"
className="w-5 h-5 rounded-full shadow-md transform transition-transform relative z-50 -ml-1"
/>
<img
src={thumb}
alt="thumb"
className="w-5 h-5 rounded-full shadow-md transform transition-transform relative z-20 -ml-2"
className="w-5 h-5 rounded-full shadow-md transform transition-transform relative z-30 -ml-2"
/>
<img
src={hand5}
alt="hand"
className="w-5 h-5 rounded-full shadow-md transform transition-transform relative z-30 -ml-2"
className="w-5 h-5 rounded-full shadow-md transform transition-transform relative z-20 -ml-2"
/>
</div>
{/* Reaction Count */}
<div className="ml-1 hover:underline underline-offset-1" onClick={() => setShowReactions(true)}>1.1k</div>
<div className="ml-1 hover:underline underline-offset-1 " onClick={() => setShowReactions(true)}>{ allReactions?.length}</div>
</div>

{/* Comments Count */}
<div className="ml-4 text-neutral-70" onClick={toggleCommentSection}>
57 Comments
<div className="ml-4 text-neutral-70 hover:text-primary-500 hover:underline underline-offset-1" onClick={toggleCommentSection}>
{articleComments?.data?.length} Comments
</div>
</div>

{showReactions && (<ReactionsPopup isOpen={ showReactions} onClose={handlecloseReactionPopup} /> )}
{showReactions && (<ReactionsPopup isOpen={ showReactions} onClose={handlecloseReactionPopup} article_id={article_id} /> )}

{/* Time Posted */}
<div className="text-neutral-70 text-xs">{timeAgo(date)}</div>
Expand Down
3 changes: 2 additions & 1 deletion src/feature/Blog/components/BlogPost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ const BlogPost: React.FC<BlogPostProps> = ({images,title,content,id,date,isArtic
};

return (
<div className="each_blog_post mt-5 shadow-md p-2 max-w-[680px] self-center w-full">
<div className="each_blog_post mt-5 shadow-md p-2 max-w-[680px] self-center w-full bg-background">
{ isArticle && <BlogArticleHeader /> }
<BlogProfile id={id} date={date} />
<BlogMessage title={title} content={content} />
{!isCognitiveMode && <BlogImagery PostImages={sampleImages} />}
<BlogReactionStats
toggleCommentSection={toggleCommentSection}
date={date}
article_id={article_id}
/>
<BlogReactionSession
isCommentSectionOpen={isCommentSectionOpen}
Expand Down
2 changes: 1 addition & 1 deletion src/feature/Comments/components/CommentMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const CommentMessage: React.FC<MessageComponentProps> = ({ content,createdAt,aut

return (
<div
className={`w-[60%] max-w-[70%] p-4 ${
className={`min-w-[70%] p-4 relative ${
index % 2 === 0 ? "self-end" : "self-start"
}`}
>
Expand Down
29 changes: 26 additions & 3 deletions src/feature/Interactions/api/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { apiClient } from "../../../services/apiClient";
import { Reaction } from "../../../models/datamodels";


// Create a new reaction
const createReaction = async (reaction: Reaction) => {
console.log("Creating reaction:", reaction);
Expand Down Expand Up @@ -37,15 +36,39 @@ const getAuthorScoresByCategory = async (category: string) => {
return data;
};

// Fetch users who reacted to an article
const getReactedUsers = async (articleId: string) => {
console.log("Fetching users who reacted to article:", articleId);
const { data } = await apiClient.get(`/react/${articleId}/reacted-users`);
return data;
};

// Fetch all reactions of an article
const getArticleReactions = async (articleId: string) => {
console.log("Fetching all reactions for article:", articleId);
const { data } = await apiClient.get(`/react/${articleId}/reactions`);
return data;
};


// Fetch users grouped by reaction type for an article
const getReactionsPerType = async (articleId: string) => {
console.log(
"Fetching users grouped by reaction type for article:",
articleId
);
const { data } = await apiClient.get(
`/react/${articleId}/reactions/per-type`
);
return data;
};

export {
createReaction,
getReactionById,
updateReaction,
deleteReaction,
getAuthorScoresByCategory,

getReactedUsers,
getArticleReactions,
getReactionsPerType,
};
11 changes: 5 additions & 6 deletions src/feature/Interactions/components/ReactionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,15 @@ const ReactionModal: React.FC<ReactionModalProps> = ({isOpen,onClose,onReact,art
const reactions = [
{ icon: heart, name: "Love" },
{ icon: thumb, name: "Like" },
{ icon: smile, name: "Laugh" },
{ icon: smile, name: "smile" },
{ icon: sadface, name: "Cry" },
{ icon: clap, name: "clap" },
];

const handleReaction = (
reaction: "heart" | "smile" | "clap" | "thumb" | "sad"
) => {
const handleReaction = ( reaction: string ) => {

createReaction({ type: reaction, article_id, user_id: authUser?.id }, {
console.log({ type: reaction, article_id, user_id: authUser?.id || "" });
createReaction({ type: reaction, article_id, user_id: authUser?.id || "" }, {
onSuccess: () => {
console.log("Reaction created successfully");
}
Expand All @@ -53,7 +52,7 @@ const ReactionModal: React.FC<ReactionModalProps> = ({isOpen,onClose,onReact,art
></div>

<div
className={`absolute z-50 mt-2 bg-white border border-gray-200 shadow-lg rounded-full p-3 transition-opacity duration-400 ${
className={`absolute z-50 mt-2 bg-background shadow-lg rounded-full p-3 transition-opacity duration-400 ${
isOpen ? "opacity-100" : "opacity-0"
}`}
style={{ bottom: "40px", left: "0px" }}
Expand Down
68 changes: 68 additions & 0 deletions src/feature/Interactions/components/ReactionTab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { useEffect, useRef, useState } from "react";


interface TabsProps {
tabs: { id: number | string; title: JSX.Element }[];
activeTab: number | string;
setActiveTab: (tabId: number | string) => void;
scale?: boolean;
borderBottom?: boolean;
children?: React.ReactNode;
}

const ReactionTab: React.FC<TabsProps> = ({tabs,activeTab,setActiveTab,scale,borderBottom}) => {
const [tabStyle, setTabStyle] = useState<React.CSSProperties>({});
const tabRef = useRef<HTMLDivElement>(null);

useEffect(() => {
const activeTabElement = tabRef.current?.querySelector(
".active"
) as HTMLElement;
if (activeTabElement) {
setTabStyle({
left: activeTabElement.offsetLeft,
width: activeTabElement.offsetWidth,
});
}
}, [activeTab]);

const handleTabClick = (tabId: number | string) => {
setActiveTab(tabId);
};

return (
<div className="flex flex-col items-center backdrop-blur-sm">
{/* Tabs */}
<div
ref={tabRef}
className={`relative flex justify-between w-full ${
borderBottom ? "border-b" : ""
}`}
>
{tabs.map((tab) => (
<span
key={tab.id}
id={`tab-${tab.id}`}
className={`px-2 py-2 cursor-pointer transition-all border-b-2 -mb-0 flex items-center ${
activeTab === tab.id
? `border-primary-400 text-neutral-50 ${
scale ? "scale-110" : ""
}`
: "border-transparent text-neutral-50"
}`}
onClick={() => handleTabClick(tab.id)}
>
{tab.title}
</span>
))}
{/* Tab slider */}
<div
className="absolute bottom-0 h-[2px] bg-primary-400 transition-all duration-300"
style={tabStyle}
></div>
</div>
</div>
);
};

export default ReactionTab;
Loading

0 comments on commit bb85191

Please sign in to comment.