showing basics of the created links
This commit is contained in:
+110
-14
@@ -1,15 +1,5 @@
|
|||||||
import { BsThreeDots } from "react-icons/bs";
|
import { BsThreeDots } from "react-icons/bs";
|
||||||
import {
|
import { FaAngleDown, FaCode, FaPlus } from "react-icons/fa";
|
||||||
FaAngleDown,
|
|
||||||
FaArchive,
|
|
||||||
FaAtlassian,
|
|
||||||
FaCode,
|
|
||||||
FaCopy,
|
|
||||||
FaExternalLinkAlt,
|
|
||||||
FaFilePdf,
|
|
||||||
FaLink,
|
|
||||||
FaPlus,
|
|
||||||
} from "react-icons/fa";
|
|
||||||
|
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { Dropdown, Menu, Radio, Tooltip } from "antd";
|
import { Dropdown, Menu, Radio, Tooltip } from "antd";
|
||||||
@@ -18,12 +8,73 @@ import {
|
|||||||
useKeyboardContext,
|
useKeyboardContext,
|
||||||
} from "../../contexts/keyboardContext";
|
} from "../../contexts/keyboardContext";
|
||||||
import CreateOrUpdateLink from "../Modals/CreateOrUpdateLink";
|
import CreateOrUpdateLink from "../Modals/CreateOrUpdateLink";
|
||||||
import { useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import LinkCard from "../LinkCard";
|
import LinkCard from "../LinkCard";
|
||||||
|
import { Collections } from "../../services/collections";
|
||||||
|
import {
|
||||||
|
collection,
|
||||||
|
getFirestore,
|
||||||
|
onSnapshot,
|
||||||
|
orderBy,
|
||||||
|
query,
|
||||||
|
where,
|
||||||
|
} from "firebase/firestore";
|
||||||
|
import { useTeamDashboardContext } from "../../contexts/teamDashboardContext";
|
||||||
|
import Link, { LinkState } from "../../models/link";
|
||||||
|
import { useAuth } from "../../contexts/authContext";
|
||||||
|
|
||||||
|
const lastWeek = new Date();
|
||||||
|
lastWeek.setDate(lastWeek.getDate() - 7);
|
||||||
|
|
||||||
|
const db = getFirestore();
|
||||||
|
|
||||||
export default function Links() {
|
export default function Links() {
|
||||||
|
const { currUser } = useAuth();
|
||||||
const { handleModalType } = useKeyboardContext();
|
const { handleModalType } = useKeyboardContext();
|
||||||
|
|
||||||
|
const { team } = useTeamDashboardContext();
|
||||||
|
|
||||||
|
const [linksMap, setLinksMap] = useState<Map<string, Link>>(
|
||||||
|
new Map<string, Link>()
|
||||||
|
);
|
||||||
|
|
||||||
|
// SECTION: LISTENER for LINKS
|
||||||
|
useEffect(() => {
|
||||||
|
/**
|
||||||
|
* QUERY:
|
||||||
|
* all links for the team in the past 7 days
|
||||||
|
* order createdDate desc
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const q = query(
|
||||||
|
collection(db, Collections.links),
|
||||||
|
where("teamId", "==", team.id),
|
||||||
|
where("createdDate", ">", lastWeek),
|
||||||
|
orderBy("createdDate", "desc")
|
||||||
|
);
|
||||||
|
|
||||||
|
// return unsubscribe
|
||||||
|
return onSnapshot(q, (snapshot) => {
|
||||||
|
snapshot.docChanges().forEach((change) => {
|
||||||
|
let updatedOrNewLink = change.doc.data() as Link;
|
||||||
|
updatedOrNewLink.id = change.doc.id;
|
||||||
|
|
||||||
|
if (change.type === "added" || change.type === "modified") {
|
||||||
|
console.log("New or updated link: ", updatedOrNewLink);
|
||||||
|
|
||||||
|
// update rooms map
|
||||||
|
setLinksMap((prevMap) => {
|
||||||
|
return new Map(prevMap.set(updatedOrNewLink.id, updatedOrNewLink));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (change.type === "removed") {
|
||||||
|
// not really going to happen, more so will be archived
|
||||||
|
console.log("Removed link: ", updatedOrNewLink);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const TimePeriodFilterMenu = (
|
const TimePeriodFilterMenu = (
|
||||||
<Menu>
|
<Menu>
|
||||||
<Menu.Item key={1} disabled>
|
<Menu.Item key={1} disabled>
|
||||||
@@ -39,6 +90,50 @@ export default function Links() {
|
|||||||
LinkTypeFilter.me
|
LinkTypeFilter.me
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const allLinks = Array.from(linksMap.values());
|
||||||
|
|
||||||
|
const meLinks = allLinks.filter((link) => {
|
||||||
|
// if archived, don't show
|
||||||
|
if (link.state == LinkState.archived) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if I am the sender, then also show
|
||||||
|
if (link.createdByUserId == currUser.uid) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if I am a receiver
|
||||||
|
if (link.recipients.includes(currUser.uid)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
const teamLinks = allLinks.filter((link) => {
|
||||||
|
// not archived and does not have a recipients list
|
||||||
|
if (link.state != LinkState.archived && !link.recipients) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
const archivedLinks = allLinks.filter(
|
||||||
|
(link) => link.state == LinkState.archived
|
||||||
|
);
|
||||||
|
|
||||||
|
function getFilteredContent() {
|
||||||
|
switch (selectedTabPane) {
|
||||||
|
case LinkTypeFilter.me:
|
||||||
|
return meLinks;
|
||||||
|
case LinkTypeFilter.team:
|
||||||
|
return teamLinks;
|
||||||
|
case LinkTypeFilter.archived:
|
||||||
|
return archivedLinks;
|
||||||
|
default:
|
||||||
|
return allLinks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="p-5 flex flex-col bg-gray-100 bg-opacity-25 rounded-lg shadow-md">
|
<section className="p-5 flex flex-col bg-gray-100 bg-opacity-25 rounded-lg shadow-md">
|
||||||
{/* header row */}
|
{/* header row */}
|
||||||
@@ -140,8 +235,9 @@ export default function Links() {
|
|||||||
|
|
||||||
{/* table of links */}
|
{/* table of links */}
|
||||||
<div className="flex flex-col space-y-2">
|
<div className="flex flex-col space-y-2">
|
||||||
{/* pdf example */}
|
{getFilteredContent().map((link) => (
|
||||||
<LinkCard />
|
<LinkCard key={link.id} link={link} />
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|||||||
+18
-13
@@ -4,34 +4,39 @@ import Image from "next/image";
|
|||||||
import { BsThreeDots } from "react-icons/bs";
|
import { BsThreeDots } from "react-icons/bs";
|
||||||
import LinkIcon from "./LinkIcon";
|
import LinkIcon from "./LinkIcon";
|
||||||
|
|
||||||
export default function LinkCard(props: { link?: Link }) {
|
interface ILinkCardProps {
|
||||||
|
link: Link;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function LinkCard(props: ILinkCardProps) {
|
||||||
return (
|
return (
|
||||||
<span className="flex flex-col rounded-lg">
|
<span
|
||||||
|
onClick={() => window.open(props.link.link, "_blank")}
|
||||||
|
className="flex flex-col rounded-lg hover:cursor-pointer"
|
||||||
|
>
|
||||||
{/* attmnt header */}
|
{/* attmnt header */}
|
||||||
<span className="flex flex-row bg-gray-300 bg-opacity-25 py-5 px-3 items-center justify-start">
|
<span className="flex flex-row bg-gray-300 bg-opacity-25 py-5 px-3 items-center justify-start">
|
||||||
<LinkIcon
|
<LinkIcon className="text-4xl mr-2" linkType={props.link.type} />
|
||||||
className="text-4xl text-orange-300 mr-2"
|
|
||||||
linkType={LinkType.googleDrive}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span className="flex flex-col items-baseline mr-10 space-y-1">
|
<span className="flex flex-col items-baseline mr-10 space-y-1">
|
||||||
<span className="text-md font-bold text-white">report.pdf</span>
|
<span className="text-md font-bold text-white">
|
||||||
|
{props.link.name}
|
||||||
|
</span>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
className={`text-gray-200 text-xs mb-auto text-ellipsis whitespace-pre-line max-h-10 overflow-hidden`}
|
className={`text-gray-200 text-xs mb-auto text-ellipsis whitespace-pre-line max-h-10 overflow-hidden`}
|
||||||
>
|
>
|
||||||
{"asdfaSdfasdfsadfsdf"}
|
{props.link.description}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{/* attachment actions */}
|
{/* attachment actions */}
|
||||||
<button className="bg-gray-300 bg-opacity-25 p-2 ml-auto rounded hover:bg-opacity-40">
|
<button
|
||||||
|
onClick={() => window.open(props.link.link, "_blank")}
|
||||||
|
className="bg-gray-300 bg-opacity-25 p-2 ml-auto rounded hover:bg-opacity-40"
|
||||||
|
>
|
||||||
<FaExternalLinkAlt className="text-sm text-white" />
|
<FaExternalLinkAlt className="text-sm text-white" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button className="bg-orange-300 bg-opacity-25 p-2 ml-2 rounded hover:bg-opacity-40">
|
|
||||||
<FaArchive className="text-sm text-orange-500 " />
|
|
||||||
</button>
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{/* attmnt footer */}
|
{/* attmnt footer */}
|
||||||
|
|||||||
Reference in New Issue
Block a user