diff --git a/src/Interfaces/ICommon.ts b/src/Interfaces/ICommon.ts index f71b936a6..3b5dae95b 100644 --- a/src/Interfaces/ICommon.ts +++ b/src/Interfaces/ICommon.ts @@ -29,3 +29,10 @@ export interface ISubHeaderProps { showLeftNav: boolean; showRightNav: boolean; } + +export interface IconProps { + title: string; + active?: boolean; + c1?: string; + c2?: string; +} diff --git a/src/Interfaces/index.ts b/src/Interfaces/index.ts index e3d3bb818..343ad0fa9 100644 --- a/src/Interfaces/index.ts +++ b/src/Interfaces/index.ts @@ -1,5 +1,5 @@ import { ISubGoalHistory } from "@src/store/GoalsState"; -import { GoalItem } from "@src/models/GoalItem"; +import { GoalItem, IParticipant } from "@src/models/GoalItem"; import { ILanguage, ILanguageListProps } from "./ILanguage"; import { confirmActionState } from "./IPopupModals"; @@ -20,6 +20,7 @@ export interface ILocationState { changeTheme?: boolean; // theme changer mode expandedGoalId?: string; // id of goal to be expanded displayGoalActions?: GoalItem; // id of goal whose actions have to be opened - displayPartner?: boolean; // whether or not to display the partner goals + displayPartnerMode?: boolean; // whether or not to display the partner goals displayAddContact?: boolean; // whether or not to display the add contact form + displayParticipants?: IParticipant[]; // whether or not to display the participants } diff --git a/src/api/GoalsAPI/index.ts b/src/api/GoalsAPI/index.ts index 44b405d83..a09b5e826 100644 --- a/src/api/GoalsAPI/index.ts +++ b/src/api/GoalsAPI/index.ts @@ -177,7 +177,7 @@ export const updateSharedStatusOfGoal = async (id: string, relId: string, name: .where("id") .equals(id) .modify((obj: GoalItem) => { - obj.participants.push({ relId, name, type: "sharer" }); + obj.participants.push({ relId, name, type: "sharer", following: false }); }); }).catch((e) => { console.log(e.stack || e); diff --git a/src/api/PartnerAPI/index.ts b/src/api/PartnerAPI/index.ts index 6ae8ad832..4596e623b 100644 --- a/src/api/PartnerAPI/index.ts +++ b/src/api/PartnerAPI/index.ts @@ -8,9 +8,8 @@ export const getPartnerByRelId = async (relId: string) => { return partner.length > 0 ? partner[0] : null; }; -export const getMyPartner = async () => { - const partner: PartnerItem[] = await db.partnersCollection.toArray(); - return partner.length > 0 ? partner[0] : null; +export const getPartnersCount = async () => { + return db.partnersCollection.count(); }; export const createPartner = async (relId: string, name: string) => { diff --git a/src/assets/images/peopleIllustration.svg b/src/assets/images/peopleIllustration.svg deleted file mode 100644 index 9c8378074..000000000 --- a/src/assets/images/peopleIllustration.svg +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/common/Icon.tsx b/src/common/Icon.tsx index d59c41404..69e586ec5 100644 --- a/src/common/Icon.tsx +++ b/src/common/Icon.tsx @@ -1,10 +1,11 @@ +import { IconProps } from "@src/Interfaces/ICommon"; import React from "react"; -const Icon = ({ title, active }: { title: string; active: boolean }) => { +const Icon: React.FC = ({ title, active, c1, c2 }) => { const color1 = active ? "var(--icon-grad-1)" : "#B1B1B1"; + // console.log("🚀 ~ file: Icon.tsx:6 ~ color1:", color1) const color2 = active ? "var(--icon-grad-2)" : "#B1B1B1"; - console.log("🚀 ~ file: Icon.tsx:5 ~ Icon ~ color1:", color1); - console.log("🚀 ~ file: Icon.tsx:7 ~ Icon ~ color2:", color2); + // console.log("🚀 ~ file: Icon.tsx:8 ~ color2:", color2) switch (title) { case "GoalsIcon": return ( @@ -248,6 +249,103 @@ const Icon = ({ title, active }: { title: string; active: boolean }) => { ); + case "ThreeAvatars": + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); case "Correct": return ( diff --git a/src/components/BottomNavbar/BottomNavbar.scss b/src/components/BottomNavbar/BottomNavbar.scss index 54ead7400..d1194bc03 100644 --- a/src/components/BottomNavbar/BottomNavbar.scss +++ b/src/components/BottomNavbar/BottomNavbar.scss @@ -1,15 +1,3 @@ -.bottom-navbar, -.bottom-navbar-dark { - position: fixed; - bottom: 0; - display: flex; - background: var(--bottom-nav-color); - width: 100%; - max-width: 600px; - height: 56px; - box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3); -} - .bottom-nav-item { width: 100%; max-width: 200px; diff --git a/src/components/BottomNavbar/BottomNavbar.tsx b/src/components/BottomNavbar/BottomNavbar.tsx index 81aab55ca..ff795b810 100644 --- a/src/components/BottomNavbar/BottomNavbar.tsx +++ b/src/components/BottomNavbar/BottomNavbar.tsx @@ -6,6 +6,7 @@ import { useLocation, useNavigate } from "react-router-dom"; import { darkModeState } from "@src/store"; import { themeSelectionMode, themeState } from "@src/store/ThemeState"; +import BottomNavLayout from "@src/layouts/BottomNavLayout"; import Backdrop from "@src/common/Backdrop"; import GlobalAddBtn from "@components/GlobalAddBtn"; @@ -70,7 +71,7 @@ const BottomNavbar = ({ title }: { title: string }) => { }} /> )} -
+ -
+ ); }; diff --git a/src/components/GlobalAddBtn.tsx b/src/components/GlobalAddBtn.tsx index fb422602f..d916bca8e 100644 --- a/src/components/GlobalAddBtn.tsx +++ b/src/components/GlobalAddBtn.tsx @@ -5,7 +5,6 @@ import { useRecoilValue } from "recoil"; import GlobalAddIcon from "@assets/images/globalAdd.svg"; import correct from "@assets/images/correct.svg"; -import { darkModeState } from "@src/store"; import { themeSelectionMode } from "@src/store/ThemeState"; import useGoalStore from "@src/hooks/useGoalStore"; @@ -16,14 +15,13 @@ const GlobalAddBtn = ({ add }: { add: string }) => { const { handleAddGoal } = useGoalStore(); const { handleAddFeeling } = useFeelingStore(); - const darkModeStatus = useRecoilValue(darkModeState); const themeSelection = useRecoilValue(themeSelectionMode); const handleClick = async (e: React.MouseEvent) => { e.stopPropagation(); if (themeSelection) { window.history.back(); - } else if (add === "myGoals" || state.displayPartner) { + } else if (add === "myGoals" || state.displayPartnerMode) { await handleAddGoal(); } else if (add === "myJournal") { handleAddFeeling(); diff --git a/src/components/GoalsComponents/GoalAvatar.tsx b/src/components/GoalsComponents/GoalAvatar.tsx new file mode 100644 index 000000000..bb8c26b3a --- /dev/null +++ b/src/components/GoalsComponents/GoalAvatar.tsx @@ -0,0 +1,62 @@ +import Icon from "@src/common/Icon"; +import { GoalItem } from "@src/models/GoalItem"; +import { openInbox } from "@src/store"; +import { getSvgForGoalPps } from "@src/utils"; +import { Tooltip } from "antd"; +import React from "react"; +import { useLocation, useNavigate } from "react-router-dom"; +import { useRecoilValue } from "recoil"; + +const Avatar = ({ goal }: { goal: GoalItem }) => { + const location = useLocation(); + const navigate = useNavigate(); + const { participants, goalColor } = goal; + const participantsSvg = getSvgForGoalPps(participants.length); + + return ( +
+ +
+ ); +}; + +const GoalAvatar = ({ goal }: { goal: GoalItem }) => { + const isInboxOpen = useRecoilValue(openInbox); + + return isInboxOpen ? ( + +
+ +
+
+ ) : ( + + ); +}; + +export default GoalAvatar; diff --git a/src/components/GoalsComponents/GoalConfigModal/ConfigGoal.tsx b/src/components/GoalsComponents/GoalConfigModal/ConfigGoal.tsx index 64913f485..c66f8077e 100644 --- a/src/components/GoalsComponents/GoalConfigModal/ConfigGoal.tsx +++ b/src/components/GoalsComponents/GoalConfigModal/ConfigGoal.tsx @@ -2,7 +2,7 @@ import moment from "moment"; import { useTranslation } from "react-i18next"; import React, { useEffect, useState } from "react"; import { Checkbox, Modal } from "antd"; -import { darkModeState, displayToast, openDevMode, partnerDetails } from "@src/store"; +import { darkModeState, displayToast, openDevMode } from "@src/store"; import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; import { useLocation } from "react-router-dom"; @@ -49,7 +49,6 @@ const ConfigGoal = ({ goal, action }: { action: "Update" | "Create"; goal: GoalI const theme = useRecoilValue(themeState); const today = moment(new Date()).format("YYYY-MM-DD"); - const partner = useRecoilValue(partnerDetails); const darkModeStatus = useRecoilValue(darkModeState); const subGoalsHistory = useRecoilValue(goalsHistory); const ancestors = subGoalsHistory.map((ele) => ele.goalID); @@ -117,7 +116,7 @@ const ConfigGoal = ({ goal, action }: { action: "Update" | "Create"; goal: GoalI return; } const goalColor = colorPalleteList[colorIndex]; - if (state.displayPartner) { + if (state.displayPartnerMode) { // suggestChanges(getFinalTags(), title, goalColor, subGoalsHistory.length); } else { await modifyGoal(goal.id, getFinalTags(), title, goalColor, ancestors); @@ -128,32 +127,32 @@ const ConfigGoal = ({ goal, action }: { action: "Update" | "Create"; goal: GoalI if (!showAddGoal) { return; } - if (state.displayPartner && partner && state.goalsHistory) { - // const parentId = state.goalsHistory.slice(-1)[0].goalID; - // const rootGoalId = state.goalsHistory[0].goalID; - // const rootGoal = partner.goals.find((ele) => ele.id === rootGoalId); - // const parentGoal = parentId === rootGoalId ? rootGoal : await getSharedWMGoal(parentId); - // if (!parentGoal || !rootGoal) { - // return; - // } - // suggestNewGoal(rootGoal, parentGoal, getFinalTags(), title, colorPalleteList[colorIndex], subGoalsHistory.length); - } else { - const { parentGoal } = await createGoal( - showAddGoal.goalId, - getFinalTags(), - title, - colorPalleteList[colorIndex], - ancestors, - ); - if (!parentGoal && title === "magic") { - setDevMode(true); - setShowToast({ - open: true, - message: "Congratulations, you activated DEV mode", - extra: "Explore what's hidden", - }); - } + // if (state.displayPartnerMode && partner && state.goalsHistory) { + // // const parentId = state.goalsHistory.slice(-1)[0].goalID; + // // const rootGoalId = state.goalsHistory[0].goalID; + // // const rootGoal = partner.goals.find((ele) => ele.id === rootGoalId); + // // const parentGoal = parentId === rootGoalId ? rootGoal : await getSharedWMGoal(parentId); + // // if (!parentGoal || !rootGoal) { + // // return; + // // } + // // suggestNewGoal(rootGoal, parentGoal, getFinalTags(), title, colorPalleteList[colorIndex], subGoalsHistory.length); + // } else { + const { parentGoal } = await createGoal( + showAddGoal.goalId, + getFinalTags(), + title, + colorPalleteList[colorIndex], + ancestors, + ); + if (!parentGoal && title === "magic") { + setDevMode(true); + setShowToast({ + open: true, + message: "Congratulations, you activated DEV mode", + extra: "Explore what's hidden", + }); } + // } await mySound.play(); }; diff --git a/src/components/GoalsComponents/GoalSublist/GoalSublist.tsx b/src/components/GoalsComponents/GoalSublist/GoalSublist.tsx index d6dbb1f82..25811ccf1 100644 --- a/src/components/GoalsComponents/GoalSublist/GoalSublist.tsx +++ b/src/components/GoalsComponents/GoalSublist/GoalSublist.tsx @@ -5,7 +5,7 @@ import { GoalItem } from "@src/models/GoalItem"; import { getChildrenGoals, getGoal } from "@src/api/GoalsAPI"; import { createGoalObjectFromTags } from "@src/helpers/GoalProcessor"; import { getSharedWMChildrenGoals, getSharedWMGoal } from "@src/api/SharedWMAPI"; -import { displayPartner, lastAction, openInbox } from "@src/store"; +import { displayPartnerMode, lastAction, openInbox } from "@src/store"; import { displayAddGoal, displayChangesModal, @@ -29,7 +29,7 @@ export const GoalSublist = () => { const showUpdateGoal = useRecoilValue(displayUpdateGoal); const showChangesModal = useRecoilValue(displayChangesModal); const showSuggestionModal = useRecoilValue(displaySuggestionsModal); - const showPartner = useRecoilValue(displayPartner); + const showPartnerMode = useRecoilValue(displayPartnerMode); const [parentGoal, setParentGoal] = useState(null); const [childrenGoals, setChildrenGoals] = useState([]); const [archivedChildren, setArchivedChildren] = useState([]); @@ -41,13 +41,17 @@ export const GoalSublist = () => { }; useEffect(() => { - (isInboxOpen || showPartner ? getSharedWMGoal(goalID) : getGoal(goalID)).then((parent) => setParentGoal(parent)); + (isInboxOpen || showPartnerMode ? getSharedWMGoal(goalID) : getGoal(goalID)).then((parent) => + setParentGoal(parent), + ); }, [goalID]); useEffect(() => { - (isInboxOpen || showPartner ? getSharedWMChildrenGoals(goalID) : getChildrenGoals(goalID)).then((fetchedGoals) => { - handleChildrenGoals(fetchedGoals); - }); + (isInboxOpen || showPartnerMode ? getSharedWMChildrenGoals(goalID) : getChildrenGoals(goalID)).then( + (fetchedGoals) => { + handleChildrenGoals(fetchedGoals); + }, + ); }, [action, parentGoal, showAddGoal, showSuggestionModal, showChangesModal, showUpdateGoal]); return ( diff --git a/src/components/GoalsComponents/MyGoal.tsx b/src/components/GoalsComponents/MyGoal.tsx index 3dfcda282..ae3d2e9e7 100644 --- a/src/components/GoalsComponents/MyGoal.tsx +++ b/src/components/GoalsComponents/MyGoal.tsx @@ -1,23 +1,20 @@ -import { Tooltip } from "antd"; import React, { useEffect } from "react"; +import { useTranslation } from "react-i18next"; import { useLocation, useNavigate } from "react-router-dom"; import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; import pencil from "@assets/images/pencil.svg"; -import mainAvatarDark from "@assets/images/mainAvatarDark.svg"; -import mainAvatarLight from "@assets/images/mainAvatarLight.svg"; import { unarchiveIcon } from "@src/assets"; -import useGoalStore from "@src/hooks/useGoalStore"; -import NotificationSymbol from "@src/common/NotificationSymbol"; import { GoalItem } from "@src/models/GoalItem"; +import { getSvgForGoalPps } from "@src/utils"; import { unarchiveUserGoal } from "@src/api/GoalsAPI"; -import { darkModeState, displayPartner, lastAction, openInbox } from "@src/store"; import { replaceUrlsWithText, summarizeUrl } from "@src/utils/patterns"; -import { getHistoryUptoGoal, jumpToLowestChanges } from "@src/helpers/GoalProcessor"; +import { darkModeState, displayPartnerMode, lastAction, openInbox } from "@src/store"; import { displayGoalId, displayUpdateGoal, goalsHistory, displayChangesModal } from "@src/store/GoalsState"; +import useGoalStore from "@src/hooks/useGoalStore"; -import { useTranslation } from "react-i18next"; +import GoalAvatar from "./GoalAvatar"; interface MyGoalProps { goal: GoalItem; @@ -63,10 +60,10 @@ const GoalSent = ({ goal }: { goal: GoalItem }) => { {goal.beforeTime && goal.afterTime ? `${t("between")} ${goal.afterTime}-${goal.beforeTime}` : goal.beforeTime - ? `${t("before")} ${goal.beforeTime}` - : goal.afterTime - ? `${t("after")} ${goal.afterTime}` - : ""} + ? `${t("before")} ${goal.beforeTime}` + : goal.afterTime + ? `${t("after")} ${goal.afterTime}` + : ""} {showStart && !!goal.start && (
@@ -85,17 +82,17 @@ const MyGoal: React.FC = ({ goal, showActions, setShowActions }) => // const sharedWithContact = goal.shared.contacts.length > 0 ? goal.shared.contacts[0].name : null; // const collabWithContact = // goal.collaboration.collaborators.length > 0 ? goal.collaboration.collaborators[0].name : null; - + const participantsSvg = getSvgForGoalPps(goal.participants.length); const navigate = useNavigate(); const location = useLocation(); - const { handleDisplayChanges, handleUpdateGoal } = useGoalStore(); + const { handleUpdateGoal } = useGoalStore(); const darkModeStatus = useRecoilValue(darkModeState); const showUpdateGoal = useRecoilValue(displayUpdateGoal); const [selectedGoalId, setSelectedGoalId] = useRecoilState(displayGoalId); const [showChangesModal, setShowChangesModal] = useRecoilState(displayChangesModal); const [subGoalHistory, setSubGoalHistory] = useRecoilState(goalsHistory); const isInboxOpen = useRecoilValue(openInbox); - const showPartner = useRecoilValue(displayPartner); + const showPartnerMode = useRecoilValue(displayPartnerMode); const setLastAction = useSetRecoilState(lastAction); const { urlsWithIndexes, replacedString } = replaceUrlsWithText(goal.title); @@ -165,7 +162,7 @@ const MyGoal: React.FC = ({ goal, showActions, setShowActions }) => }, [location]); const isActionVisible = () => { - return !archived && !isInboxOpen && !showPartner && showActions.open === goal.id && showActions.click > 0; + return !archived && !isInboxOpen && !showPartnerMode && showActions.open === goal.id && showActions.click > 0; }; return ( @@ -271,29 +268,7 @@ const MyGoal: React.FC = ({ goal, showActions, setShowActions }) => )}
- {goal.participants.length > 0 && ( - -
- {goal.participants[0].type === "collaborator" && ( - collaborate goal - )} - -
-
- )} + {goal.participants.length > 0 && } {archived && (
+
+ ))} + + + ); +}; + +export default Participants; diff --git a/src/components/GoalsComponents/ShareGoalModal/ShareGoalModal.tsx b/src/components/GoalsComponents/ShareGoalModal/ShareGoalModal.tsx index d6ed66e63..8a2d39ad4 100644 --- a/src/components/GoalsComponents/ShareGoalModal/ShareGoalModal.tsx +++ b/src/components/GoalsComponents/ShareGoalModal/ShareGoalModal.tsx @@ -4,8 +4,6 @@ import { useLocation, useNavigate } from "react-router-dom"; import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; import GlobalAddIcon from "@assets/images/globalAdd.svg"; -import shareAnonymous from "@assets/images/shareAnonymous.svg"; -import shareWithFriend from "@assets/images/shareWithFriend.svg"; import Loader from "@src/common/Loader"; import ContactItem from "@src/models/ContactItem"; @@ -61,7 +59,7 @@ const ShareGoalModal = ({ goal }: { goal: GoalItem }) => { ...ele, participants: [], parentGoalId: ele.id === goal.id ? "root" : ele.parentGoalId, - rootGoalId: ele.id === goal.id ? "root" : goal.id, + rootGoalId: goal.id, })), ]); setShowToast({ open: true, message: `Cheers!!, Your goal is shared with ${name}`, extra: "" }); @@ -129,8 +127,9 @@ const ShareGoalModal = ({ goal }: { goal: GoalItem }) => { centered style={showAddContactModal ? { zIndex: 1 } : {}} onCancel={() => window.history.back()} - className={`share-modal${darkModeStatus ? "-dark" : ""} popupModal${darkModeStatus ? "-dark" : ""} ${darkModeStatus ? "dark" : "light" - }-theme${theme[darkModeStatus ? "dark" : "light"]}`} + className={`share-modal${darkModeStatus ? "-dark" : ""} popupModal${darkModeStatus ? "-dark" : ""} ${ + darkModeStatus ? "dark" : "light" + }-theme${theme[darkModeStatus ? "dark" : "light"]}`} > {confirmationAction && }

{displaySubmenu === "groups" ? "Share in Public Group" : "Share Goals"}

@@ -148,7 +147,7 @@ const ShareGoalModal = ({ goal }: { goal: GoalItem }) => { ) : (
- + {/* share goal pseudo anonymously */}
)} @@ -171,8 +170,7 @@ const ShareGoalModal = ({ goal }: { goal: GoalItem }) => { ) : (
- - +
)}

Share privately

diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 7ed80cd4f..5d691312b 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -10,17 +10,10 @@ import searchIcon from "@assets/images/searchIcon.svg"; import darkModeIcon from "@assets/images/darkModeIcon.svg"; import lightModeIcon from "@assets/images/lightModeIcon.svg"; -import { - darkModeState, - displayInbox, - displayPartner, - displayToast, - openInbox, - partnerDetails, - searchActive, -} from "@src/store"; import { IHeader } from "@src/Interfaces/ICommon"; import { goalsHistory } from "@src/store/GoalsState"; +import { getPartnersCount } from "@src/api/PartnerAPI"; +import { darkModeState, displayInbox, displayPartnerMode, displayToast, openInbox, searchActive } from "@src/store"; import HeaderBtn from "./HeaderBtn"; import Search from "../../common/Search"; @@ -33,17 +26,17 @@ const Header: React.FC = ({ title, debounceSearch }) => { const navigate = useNavigate(); const setShowToast = useSetRecoilState(displayToast); - const partner = useRecoilValue(partnerDetails); const showInbox = useRecoilValue(displayInbox); const darkModeStatus = useRecoilValue(darkModeState); const subGoalHistory = useRecoilValue(goalsHistory); const [isInboxOpen, setIsInboxOpen] = useRecoilState(openInbox); - const [showPartner, setShowPartner] = useRecoilState(displayPartner); + const [showPartnerMode, setShowPartnerMode] = useRecoilState(displayPartnerMode); const [displaySearch, setDisplaySearch] = useRecoilState(searchActive); const handlePartner = async () => { - if (!partner) { + const doesParnterExist = await getPartnersCount(); + if (!doesParnterExist) { setShowToast({ open: true, message: "Do you have a partner?", @@ -51,13 +44,12 @@ const Header: React.FC = ({ title, debounceSearch }) => { }); return; } - if (showPartner) { + if (showPartnerMode) { window.history.back(); - } - if (partner) { + } else { navigate("/MyGoals", { state: { - displayPartner: true, + displayPartnerMode: true, }, }); } @@ -69,8 +61,8 @@ const Header: React.FC = ({ title, debounceSearch }) => { } if (displaySearch || locationState?.displaySearch) { setDisplaySearch(locationState?.displaySearch || false); - } else if (showPartner || locationState?.displayPartner) { - setShowPartner(locationState?.displayPartner || false); + } else if (showPartnerMode || locationState?.displayPartnerMode) { + setShowPartnerMode(locationState?.displayPartnerMode || false); } }; diff --git a/src/components/Header/HeaderBtn.tsx b/src/components/Header/HeaderBtn.tsx index 50c24cb01..d2a52074b 100644 --- a/src/components/Header/HeaderBtn.tsx +++ b/src/components/Header/HeaderBtn.tsx @@ -32,10 +32,10 @@ const HeaderBtn = ({ path, alt }: { path: string; alt: string }) => { } else if (alt === "light mode") { localStorage.setItem("darkMode", darkModeStatus ? "off" : "on"); setDarkModeStatus(!darkModeStatus); - } else if (alt == "dark mode") { + } else if (alt === "dark mode") { localStorage.setItem("darkMode", darkModeStatus ? "off" : "on"); setDarkModeStatus(!darkModeStatus); - } + } }; return ( diff --git a/src/components/ParticipantsNavbar.tsx b/src/components/ParticipantsNavbar.tsx new file mode 100644 index 000000000..cb69b37e0 --- /dev/null +++ b/src/components/ParticipantsNavbar.tsx @@ -0,0 +1,32 @@ +import BottomNavLayout from "@src/layouts/BottomNavLayout"; +import ContactItem from "@src/models/ContactItem"; +import React from "react"; + +const ParticipantsNavbar = ({ + list, + activePartner, + setActivePartner, +}: { + list: ContactItem[]; + setActivePartner: React.Dispatch>; + activePartner: string; +}) => { + return ( + + {list.map((contact) => ( + + ))} + + ); +}; + +export default ParticipantsNavbar; diff --git a/src/helpers/GoalActionHelper.tsx b/src/helpers/GoalActionHelper.tsx index a5ee776bc..cf07541f8 100644 --- a/src/helpers/GoalActionHelper.tsx +++ b/src/helpers/GoalActionHelper.tsx @@ -11,12 +11,12 @@ export const removeThisGoal = async ( goal: GoalItem, ancestors: string[], isInboxOpen: boolean, - showPartner: boolean, + showPartnerMode: boolean, ) => { await pageCrumple.play(); if (isInboxOpen) { await moveToPartner(goal); - } else if (showPartner) { + } else if (showPartnerMode) { await deleteSharedGoal(goal); } else { await deleteGoal(goal, ancestors); diff --git a/src/helpers/GoalLocStateHandler.tsx b/src/helpers/GoalLocStateHandler.tsx index ee0840b0d..27f07bd9b 100644 --- a/src/helpers/GoalLocStateHandler.tsx +++ b/src/helpers/GoalLocStateHandler.tsx @@ -12,6 +12,7 @@ import { displayShareModal, displayGoalActions, displayAddContact, + displayParticipants, } from "@src/store/GoalsState"; const GoalLocStateHandler = () => { @@ -24,6 +25,7 @@ const GoalLocStateHandler = () => { const [showUpdateGoal, setShowUpdateGoal] = useRecoilState(displayUpdateGoal); const [showShareModal, setShowShareModal] = useRecoilState(displayShareModal); const [showGoalActions, setShowGoalActions] = useRecoilState(displayGoalActions); + const [showParticipants, setShowParticipants] = useRecoilState(displayParticipants); const [showConfirmation, setShowConfirmation] = useRecoilState(displayConfirmation); const [showAddContactModal, setShowAddContactModal] = useRecoilState(displayAddContact); @@ -42,6 +44,11 @@ const GoalLocStateHandler = () => { setSubGoalHistory([...(locationState.goalsHistory || [])]); setSelectedGoalId(locationState.activeGoalId || "root"); } + if (showParticipants && !locationState.displayParticipants) { + setShowParticipants(null); + } else if (locationState.displayParticipants) { + setShowParticipants(locationState.displayParticipants); + } if (showGoalActions && !locationState.displayGoalActions) { setShowGoalActions(null); } else if (locationState.displayGoalActions) { diff --git a/src/helpers/InboxProcessor.ts b/src/helpers/InboxProcessor.ts index b220b7100..671c8f4fb 100644 --- a/src/helpers/InboxProcessor.ts +++ b/src/helpers/InboxProcessor.ts @@ -24,8 +24,12 @@ import { import { IDisplayChangesModal, ITagChangesSchemaVersion, ITagsChanges } from "@src/Interfaces/IDisplayChangesModal"; import { fixDateVlauesInGoalObject } from "@src/utils"; -export const handleIncomingChanges = async (payload) => { +export const handleIncomingChanges = async (payload, relId) => { if (payload.type === "sharer") { + const goal = await getGoal(payload.rootGoalId); + if (!goal || goal.participants.find((ele) => ele.relId === relId && ele.following) === undefined) { + return; + } if (payload.changeType === "subgoals") { const changes = [ ...payload.changes.map((ele: changesInGoal) => ({ ...ele, goal: fixDateVlauesInGoalObject(ele.goal) })), diff --git a/src/layouts/BottomNavLayout.tsx b/src/layouts/BottomNavLayout.tsx new file mode 100644 index 000000000..f98458541 --- /dev/null +++ b/src/layouts/BottomNavLayout.tsx @@ -0,0 +1,20 @@ +import React from "react"; + +const BottomNavLayout = ({ children }: { children: React.ReactNode }) => ( +
+ {children} +
+); + +export default BottomNavLayout; diff --git a/src/models/GoalItem.ts b/src/models/GoalItem.ts index e6b8c13c4..870ded652 100644 --- a/src/models/GoalItem.ts +++ b/src/models/GoalItem.ts @@ -4,6 +4,7 @@ export interface IParticipant { relId: string; name: string; type: typeOfSub; + following: boolean; } export interface GoalItem { diff --git a/src/models/db.ts b/src/models/db.ts index 774e190ff..2f38401b4 100644 --- a/src/models/db.ts +++ b/src/models/db.ts @@ -9,7 +9,7 @@ import { GCustomItem } from "./GCustomItem"; import { DumpboxItem } from "./DumpboxItem"; import { PartnerItem } from "./PartnerItem"; -export const dexieVersion = 12; +export const dexieVersion = 13; const currentVersion = localStorage.getItem("dexieVersion") || dexieVersion; localStorage.setItem("dexieVersion", `${dexieVersion}`); @@ -94,6 +94,17 @@ export class ZinZenDB extends Dexie { goal.participants = []; }); } + if (currentVersion < 13) { + console.log("processing updates for 10th version"); + const sharedWMCollection = trans.table("sharedWMCollection"); + const goalsCollection = trans.table("goalsCollection"); + sharedWMCollection.toCollection().modify((goal: GoalItem) => { + goal.participants = goal.participants.map((ele) => ({ ...ele, following: false })); + }); + goalsCollection.toCollection().modify((goal: GoalItem) => { + goal.participants = goal.participants.map((ele) => ({ ...ele, following: false })); + }); + } }); } } diff --git a/src/pages/GoalsPage/GoalsPage.scss b/src/pages/GoalsPage/GoalsPage.scss index 30c4d044b..5377111d7 100644 --- a/src/pages/GoalsPage/GoalsPage.scss +++ b/src/pages/GoalsPage/GoalsPage.scss @@ -62,11 +62,20 @@ border-radius: 50%; width: 24px; height: 24px; - font-size: 1em; + + padding: 0; + display: flex; + align-items: center; + justify-content: center; } } } +.pps-icon > svg { + width: 16px; + height: 16px; +} + .goal-dropdown, .goal-dd-inner, .goal-dd-outer { diff --git a/src/pages/GoalsPage/GoalsPage.tsx b/src/pages/GoalsPage/GoalsPage.tsx index cf4afd271..0481dbef7 100644 --- a/src/pages/GoalsPage/GoalsPage.tsx +++ b/src/pages/GoalsPage/GoalsPage.tsx @@ -1,9 +1,15 @@ -import React, { useEffect } from "react"; -import { useRecoilState, useRecoilValue } from "recoil"; +import { useRecoilValue } from "recoil"; +import React, { useEffect, useState } from "react"; -import { getMyPartner } from "@src/api/PartnerAPI"; -import { displayShareModal } from "@src/store/GoalsState"; -import { displayPartner, partnerDetails } from "@src/store"; +import { PartnerItem } from "@src/models/PartnerItem"; +import { getAllContacts } from "@src/api/ContactsAPI"; +import { getPartnerByRelId } from "@src/api/PartnerAPI"; +import { displayPartnerMode } from "@src/store"; +import { displayParticipants } from "@src/store/GoalsState"; + +import ContactItem from "@src/models/ContactItem"; +import Participants from "@components/GoalsComponents/Participants"; +import ParticipantsNavbar from "@components/ParticipantsNavbar"; import GoalLocStateHandler from "@src/helpers/GoalLocStateHandler"; import { MyGoals } from "./MyGoals"; @@ -11,24 +17,42 @@ import PartnerGoals from "./PartnerGoals"; import "./GoalsPage.scss"; const GoalsPage = () => { - const [partner, setPartner] = useRecoilState(partnerDetails); - const showPartner = useRecoilValue(displayPartner); - const showShareModal = useRecoilValue(displayShareModal); - - const getPartnerGoals = async () => { - const myPartner = await getMyPartner(); - if (myPartner) { - setPartner(JSON.parse(JSON.stringify(myPartner))); + const showPartnerMode = useRecoilValue(displayPartnerMode); + const showParticipants = useRecoilValue(displayParticipants); + + const [activePartner, setActivePartner] = useState(""); + const [partner, setPartner] = useState(null); + const [partnersList, setPartnersList] = useState([]); + + const getPartnerDetails = async () => { + let activeRelId; + if (partnersList.length > 0) { + activeRelId = partnersList[0].relId; + } else { + const list = await getAllContacts(); + activeRelId = list[0].relId; + setPartnersList([...list]); } + setActivePartner(activeRelId); + setPartner(await getPartnerByRelId(activeRelId)); }; + useEffect(() => { - getPartnerGoals(); - }, [showPartner, showShareModal]); + getPartnerDetails(); + }, [showPartnerMode, activePartner]); return ( <> - {showPartner && partner ? : } + {showParticipants && } + {showPartnerMode && partner ? ( + <> + + + + ) : ( + + )} ); }; diff --git a/src/store/GoalsState.ts b/src/store/GoalsState.ts index 70502a688..dfa276db9 100644 --- a/src/store/GoalsState.ts +++ b/src/store/GoalsState.ts @@ -1,6 +1,6 @@ // @ts-nocheck import { atom } from "recoil"; -import { GoalItem } from "@src/models/GoalItem"; +import { GoalItem, IParticipant } from "@src/models/GoalItem"; import { IDisplayChangesModal } from "@src/Interfaces/IDisplayChangesModal"; export interface ISubGoalHistory { @@ -34,6 +34,11 @@ export const displayShareModal = atom({ default: null as GoalItem | null, }); +export const displayParticipants = atom({ + key: "displayParticipants", + default: null as IParticipant[] | null, +}); + export const displaySuggestionsModal = atom({ key: "displaySuggestionsModal", default: { goals: [], selected: "" } as { goals: GoalItem[]; selected: string }, diff --git a/src/store/index.ts b/src/store/index.ts index 313034eaa..62b9b851d 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -75,16 +75,11 @@ export const openDevMode = atom({ default: false, }); -export const displayPartner = atom({ - key: "displayPartner", +export const displayPartnerMode = atom({ + key: "displayPartnerMode", default: false, }); -export const partnerDetails = atom({ - key: "partnerDetails", - default: null as PartnerItem | null, -}); - export const selectedMyTimeView = atom({ key: "selectedMyTimeView", default: "today", diff --git a/src/utils/index.ts b/src/utils/index.ts index 4ad9be4cf..b3829c138 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -225,3 +225,14 @@ export const formatTimeDisplay = (timeInSeconds: number) => { return { minutes, seconds }; }; + +export const getSvgForGoalPps = (count: number) => { + switch (count) { + case 1: + return "SingleAvatar"; + case 3: + return "TwoAvatars"; + default: + return "ThreeAvatars"; + } +};