Skip to content

Commit

Permalink
fix #59 - prevent creating new interview if one exists
Browse files Browse the repository at this point in the history
  • Loading branch information
GraemeFulton committed Jul 21, 2024
1 parent 8b8e4aa commit e8eb7a2
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 2 deletions.
3 changes: 2 additions & 1 deletion components/InterviewDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const InterviewDialog = ({
user,
initialEditor,
relatedPostId,
enabled,
}) => {
const [loading, setLoading] = useState(false);
const router = useRouter();
Expand Down Expand Up @@ -85,7 +86,7 @@ const InterviewDialog = ({
</p>
<div className="w-full flex justify-start">
<Button
disabled={loading}
disabled={loading || !enabled}
className="mt-6 cursor-pointe rounded-full"
onClick={async () => {
setLoading(true);
Expand Down
Binary file removed components/v4/card/.ToolCard.js.swp
Binary file not shown.
145 changes: 145 additions & 0 deletions components/v4/section/TopicsNavRow2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import Container from "@/components/container";
import GiantTag from "../tag/GiantTag";
import {Compass} from '@/components/icons'
import { useEffect, useState } from "react";

const tags = {
accessibility: {
name: "Accessibility",
link: "/topic/accessibility/page/1",
slug: "accessibility",
related: ["inclusive-design", "wcag", "screen-readers"]
},
ai: {
name: "AI",
link: "/topic/ai/page/1",
slug: "ai",
related: ["machine-learning", "natural-language-processing", "computer-vision"]
},
branding: {
name: "Branding",
link: "/topic/branding/page/1",
slug: "branding",
related: ["logo-design", "brand-identity", "color-theory"]
},
figma: {
name: "Figma",
link: "/topic/figma/page/1",
slug: "figma",
related: ["prototyping", "design-systems", "collaboration"]
},
notion: {
name: "Notion",
link: "/topic/notion/page/1",
slug: "notion",
related: ["productivity", "knowledge-management", "collaboration"]
},
interview: {
name: "Interview",
link: "/topic/interview/page/1",
slug: "interview",
related: ["career-advice", "job-search", "portfolio"]
},
"open-source": {
name: "Open Source",
link: "/topic/open-source/page/1",
slug: "open-source",
related: ["github", "collaboration", "community"]
},
psychology: {
name: "Psychology",
link: "/topic/design-psychology/page/1",
slug: "psychology",
related: ["cognitive-bias", "user-behavior", "emotional-design"]
},
ui: {
name: "UI",
link: "/topic/ui/page/1",
slug: "ui",
related: ["visual-design", "interaction-design", "design-systems"]
},
ux: {
name: "UX",
link: "/topic/ux/page/1",
slug: "ux",
related: ["user-research", "information-architecture", "usability"]
},
"user-research": {
name: "User Research",
link: "/topic/user-research/page/1",
slug: "user-research",
related: ["usability-testing", "interviews", "surveys"]
},
career: {
name: "Career",
link: "/topic/career/page/1",
slug: "career",
related: ["job-search", "skill-development", "networking"]
},
};

const TagsNavRow = ({currentPage, activeTag, path}) => {
const [orderedTags, setOrderedTags] = useState([])

useEffect(() => {
const reordered = orderTags(tags, activeTag, path)
setOrderedTags(reordered)
}, [activeTag, currentPage, path])

return (
<Container padding={false} maxWidth={"max-w-[1320px] mx-auto mb-4 px-3 md:px-3"}>
<div key={activeTag} className="flex flex-wrap gap-2">
<GiantTag classes={`${currentPage=='topics'?'border border-gray-800':''} pl-2 mr-3`} link={`/topics`}>
<div className="flex">
<Compass weight={`${currentPage=='topics'?'fill':'regular'}`} size={24} />
<div className="ml-2 my-auto">Explore topics</div>
</div>
</GiantTag>
{orderedTags.map((tag, index) => (
<GiantTag key={tag.slug} active={activeTag === tag.slug} link={`${tag.link || "/"}`}>
{tag.name}
</GiantTag>
))}
</div>
</Container>
);
};

const orderTags = (tags, activeTag, path) => {
const allTags = Object.values(tags);
if (!activeTag) return allTags;

const activeTagObj = tags[activeTag];
if (activeTagObj) {
// If the active tag is a top-level tag
const relatedTags = activeTagObj.related.map(slug => ({
name: slug.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' '),
link: `/${path || 'topic'}/${slug}/page/1`,
slug: slug
}));
return [activeTagObj, ...relatedTags, ...allTags.filter(tag => tag.slug !== activeTag)];
} else {
// If the active tag is a child tag
const parentTag = Object.values(tags).find(tag => tag.related.includes(activeTag));
if (parentTag) {
const activeChildTag = {
name: activeTag.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' '),
link: `/${path || 'topic'}/${activeTag}/page/1`,
slug: activeTag
};
const siblingTags = parentTag.related
.filter(slug => slug !== activeTag)
.map(slug => ({
name: slug.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' '),
link: `/${path || 'topic'}/${slug}/page/1`,
slug: slug
}));
return [activeChildTag, parentTag, ...siblingTags, ...allTags.filter(tag => tag.slug !== parentTag.slug)];
}
}

// If the active tag is not found, return all tags
return allTags;
};

export default TagsNavRow;
15 changes: 15 additions & 0 deletions lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import creatorArticlesQuery from "./queries/creatorArticlesQuery";
import getUserRelatedPostsFromPostId from "./queries/getUserRelatedPostsFromPostId";
import likeCountQuery from "./queries/likeCountQuery";
import notificationCountQuery from "./queries/notificationCountQuery";
import singlePostByToolRelation from "./queries/singlePostByToolRelation";
// import { groupNotifications } from "./notifications/groupNotifications";
/**
* main fetch
Expand Down Expand Up @@ -310,6 +311,20 @@ export async function getPost(slug, preview, type) {
data.morePosts = data.relatedPosts;
return data;
}
export async function getPostWithTool(slug, preview, type, toolId) {
const data = await fetchAPI(singlePostByToolRelation, {
preview,
variables: {
...(preview ? "" : ""),
// slug: slug,
type: type ? type : "article",
toolId: toolId
},
});

data.morePosts = data.relatedPosts;
return data;
}

export async function getSponsoredPostById(id) {
const data = await fetchAPI(sponsoredPostByIdQuery, {
Expand Down
9 changes: 9 additions & 0 deletions lib/queries/singlePostByToolRelation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default `
query PostBySlug($status: String, $slug: String, $type: String) {
posts(filters: {status:{eq:$status}, slug:{eq:$slug}, type:{eq:$type},tools:{id:{in:"13824"}} }) {
data {
id
}
}
}
`;
1 change: 1 addition & 0 deletions lib/queries/userArticle.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ query UserArticle($id:ID!) {
draft_title
excerpt
link
interviews
excerpt
localizations
owner
Expand Down
41 changes: 40 additions & 1 deletion pages/toolbox/post/[id]/interview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import useCreate from "@/components/Editor/editorHooks/newPost/useCreate";

import { useRouter } from "next/router";
import EditorNav from "@/components/EditorNav";
import { getToolById } from "@/lib/api";
import { getPostWithTool, getToolById, getUserArticle } from "@/lib/api";
import InterviewDialog from "@/components/InterviewDialog";

/**
Expand All @@ -27,18 +27,53 @@ import InterviewDialog from "@/components/InterviewDialog";
* @returns
*/
export default function InterviewEditor({ tool }) {

const router = useRouter();
const { user } = useUser({
// redirectTo: '/account',
redirectTo: "/onboard",
redirectIfFound: false,
});


const [postData, setPostData] = useState(null);
const [isDisabled, setIsDisabled] = useState(true);


useEffect(() => {
if (postData && postData.interviews && postData.interviews.length > 0) {
setIsDisabled(true);
//redirect to the interview
router.push(`/toolbox/post/${router.query.id}/interview/${postData?.interviews[0].id}`);
} else {
setIsDisabled(false);
}
}, [postData]);


useEffect(() => {
const fetchPostData = async () => {
if (user && router.query.id) {
try {
const data = await getUserArticle(user, router.query.id);
setPostData(data.userPostId);
} catch (error) {
console.error("Error fetching post data:", error);
}
}
};

fetchPostData();
}, [user, router.query.id]);


/**
* embed twitter widget if not already loaded
*/
useEffect(() => {
addTwitterScript();


}, []);

//useLoad hook
Expand Down Expand Up @@ -157,6 +192,7 @@ export default function InterviewEditor({ tool }) {
open={dialogOpen}
user={user}
relatedPostId={router.query.id}
enabled={!!postData && !isDisabled} // Enable dialog only when postData is available
/>
</>
);
Expand All @@ -166,6 +202,9 @@ export async function getStaticProps({ params, preview = null, locale }) {
let data;
try {
data = await getToolById(params.id, preview);



} catch (error) {
console.error("Failed to get tool:", error);
return {
Expand Down

0 comments on commit e8eb7a2

Please sign in to comment.