diff --git a/components/core/Filter/Content.js b/components/core/Filter/Content.js
index c87a3c8f..f47f3f1b 100644
--- a/components/core/Filter/Content.js
+++ b/components/core/Filter/Content.js
@@ -7,6 +7,7 @@ import * as Styles from "~/common/styles";
import { FileTypeGroup } from "~/components/core/FileTypeIcon";
import { css } from "@emotion/react";
import { useFilterContext } from "~/components/core/Filter/Provider";
+import { TagsOnboarding } from "~/components/core/Onboarding/Tags";
import DataView from "~/components/core/DataView";
import EmptyState from "~/components/core/EmptyState";
@@ -41,18 +42,27 @@ export function Content({ viewer, onAction, page, ...props }) {
const [{ filterState }] = useFilterContext();
const { objects } = filterState;
+ const isOnboardingActive =
+ viewer?.onboarding?.upload &&
+ !viewer?.onboarding?.tags &&
+ filterState?.type === "library" &&
+ objects.length > 0;
+
return (
{objects.length ? (
-
+
+
+
) : (
diff --git a/components/core/Onboarding/Tags.js b/components/core/Onboarding/Tags.js
new file mode 100644
index 00000000..61bade47
--- /dev/null
+++ b/components/core/Onboarding/Tags.js
@@ -0,0 +1,106 @@
+import * as React from "react";
+import * as System from "~/components/system";
+
+import { ModalPortal } from "~/components/core/ModalPortal";
+
+import OnboardingPopup from "~/components/core/Onboarding/Popup";
+
+/* -------------------------------------------------------------------------------------------------
+ * Provider
+ * -----------------------------------------------------------------------------------------------*/
+
+const TagsOnboardingContext = React.createContext();
+export const useTagsOnboardingContext = () => React.useContext(TagsOnboardingContext);
+
+const steps = {
+ tagsTrigger: "tagsTrigger",
+ tagsJumper: "tagsJumper",
+ finish: "finish",
+};
+
+function Provider({ children, viewer, ...props }) {
+ const [currentStep, setCurrentStep] = React.useState(
+ viewer?.onboarding?.tags ? steps.finish : steps.tagsTrigger
+ );
+
+ const goToNextStep = React.useCallback(() => {
+ if (currentStep === steps.finish) return;
+
+ const nextStep = {
+ tagsTrigger: "tagsJumper",
+ tagsJumper: "finish",
+ };
+ setCurrentStep((prev) => nextStep[prev]);
+ }, [currentStep]);
+
+ return (
+
+ {children}
+
+ );
+}
+
+/* -------------------------------------------------------------------------------------------------
+ * TagsWalkthrought
+ * -----------------------------------------------------------------------------------------------*/
+
+function TagsWalkthrought() {
+ const [isOrganizeTagsPopupVisible, setOrganizeTagsPopupVisiblity] = React.useState(true);
+ const hideOrganizeTagsPopup = () => setOrganizeTagsPopupVisiblity(false);
+
+ const [isTagsPrivacyPopupVisible, setTagsPrivacyPopupVisibility] = React.useState(true);
+ const hideTagsPrivacyPopup = () => setTagsPrivacyPopupVisibility(false);
+
+ const { currentStep, steps } = useTagsOnboardingContext();
+
+ if (currentStep === steps.tagsTrigger)
+ return isOrganizeTagsPopupVisible ? (
+
+
+
+ Hover over the object and click on “#” button to apply tags to it.
+
+
+ Got it
+
+
+
+ ) : null;
+
+ if (currentStep === steps.tagsJumper) {
+ return (
+
+ {isTagsPrivacyPopupVisible ? (
+
+
+ All your objects are link-access only by default. If you apply public tags on them,
+ they will show up on your profile.
+
+
+ Got it
+
+
+ ) : null}
+
+ );
+ }
+
+ return null;
+}
+
+export function TagsOnboarding({ isActive, viewer, children }) {
+ if (!isActive) return children;
+
+ return (
+
+
+ {children}
+
+ );
+}