Skip to content

Commit

Permalink
feat: Add navigation for settings page tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
flozia committed Nov 21, 2024
1 parent 5ec7db7 commit b833165
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,32 @@

"use client";

import { useState } from "react";
import { ReactNode, useEffect, useState } from "react";
import { usePathname } from "next/navigation";
import { useL10n } from "../../../../../../hooks/l10n";
import { TabType } from "../dashboard/View";
import { TabList } from "../../../../../../components/client/TabList";
import styles from "./SettingsContent.module.scss";
import { SettingsPanel } from "./panels";
import { TabType } from "./View";
import {
EmailOutlineIcon,
MailboxOutlineIcon,
ContactsOutlineIcon,
} from "../../../../../../components/server/Icons";

function SettingsContent() {
type SettingContentProps = {
activeTab: TabType;
};

type TabData = {
name: ReactNode;
key: TabType;
};

function SettingsContent(props: SettingContentProps) {
const l10n = useL10n();
const tabsData = [
const pathname = usePathname();
const tabsData: TabData[] = [
{
name: (
<>
Expand All @@ -35,7 +46,7 @@ function SettingsContent() {
{l10n.getString("settings-tab-label-notifications")}
</>
),
key: "label-notification",
key: "notifications",
},
{
name: (
Expand All @@ -47,9 +58,17 @@ function SettingsContent() {
key: "manage-account",
},
];
const [activeTab, setActiveTab] = useState<(typeof tabsData)[number]["key"]>(
tabsData[0].key,
);
const [activeTab, setActiveTab] = useState<TabType>(props.activeTab);

useEffect(() => {
const nextPathname = `/user/settings/${activeTab}`;
if (pathname !== nextPathname) {
// Directly interacting with the history API is recommended by Next.js to
// avoid re-rendering on the server:
// See https://github.com/vercel/next.js/discussions/48110#discussioncomment-7563979.
window.history.replaceState(null, "", nextPathname);
}
}, [pathname, activeTab]);

return (
<main className={styles.main}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import { ExperimentData } from "../../../../../../../telemetry/generated/nimbus/
import { SubscriberEmailPreferencesOutput } from "../../../../../../../db/tables/subscriber_email_preferences";
import { SettingsContent } from "./SettingsContent";

export type TabType = "edit-info" | "notifications" | "manage-account";

export type Props = {
l10n: ExtendedReactLocalization;
user: Session["user"];
Expand All @@ -44,6 +46,7 @@ export type Props = {
experimentData: ExperimentData;
lastScanDate?: Date;
isMonthlySubscriber: boolean;
activeTab: TabType;
};

export const SettingsView = (props: Props) => {
Expand All @@ -60,7 +63,7 @@ export const SettingsView = (props: Props) => {
experimentData={props.experimentData}
/>
{props.enabledFeatureFlags.includes("SettingsPageRedesign") ? (
<SettingsContent />
<SettingsContent activeTab={props.activeTab} />
) : (
<main className={styles.main}>
<header className={styles.title}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,62 @@

import { redirect } from "next/navigation";
import { headers } from "next/headers";
import { getServerSession } from "../../../../../../functions/server/getServerSession";
import { SettingsView } from "./View";
import { getServerSession } from "../../../../../../../functions/server/getServerSession";
import { SettingsView, TabType } from "../View";
import {
getSubscriptionBillingAmount,
getPremiumSubscriptionUrl,
} from "../../../../../../functions/server/getPremiumSubscriptionInfo";
import { getL10n } from "../../../../../../functions/l10n/serverComponents";
import { getUserEmails } from "../../../../../../../db/tables/emailAddresses";
import { getBreaches } from "../../../../../../functions/server/getBreaches";
import { getBreachesForEmail } from "../../../../../../../utils/hibp";
import { getSha1 } from "../../../../../../../utils/fxa";
import { getAttributionsFromCookiesOrDb } from "../../../../../../functions/server/attributions";
import { getEnabledFeatureFlags } from "../../../../../../../db/tables/featureFlags";
import { getLatestOnerepScan } from "../../../../../../../db/tables/onerep_scans";
import { getExperimentationId } from "../../../../../../functions/server/getExperimentationId";
import { getExperiments } from "../../../../../../functions/server/getExperiments";
import { getLocale } from "../../../../../../functions/universal/getLocale";
import { getCountryCode } from "../../../../../../functions/server/getCountryCode";
import { getSubscriberById } from "../../../../../../../db/tables/subscribers";
import { checkSession } from "../../../../../../functions/server/checkSession";
import { checkUserHasMonthlySubscription } from "../../../../../../functions/server/user";
import { getEmailPreferenceForPrimaryEmail } from "../../../../../../../db/tables/subscriber_email_preferences";
} from "../../../../../../../functions/server/getPremiumSubscriptionInfo";
import { getL10n } from "../../../../../../../functions/l10n/serverComponents";
import { getUserEmails } from "../../../../../../../../db/tables/emailAddresses";
import { getBreaches } from "../../../../../../../functions/server/getBreaches";
import { getBreachesForEmail } from "../../../../../../../../utils/hibp";
import { getSha1 } from "../../../../../../../../utils/fxa";
import { getAttributionsFromCookiesOrDb } from "../../../../../../../functions/server/attributions";
import { getEnabledFeatureFlags } from "../../../../../../../../db/tables/featureFlags";
import { getLatestOnerepScan } from "../../../../../../../../db/tables/onerep_scans";
import { getExperimentationId } from "../../../../../../../functions/server/getExperimentationId";
import { getExperiments } from "../../../../../../../functions/server/getExperiments";
import { getLocale } from "../../../../../../../functions/universal/getLocale";
import { getCountryCode } from "../../../../../../../functions/server/getCountryCode";
import { getSubscriberById } from "../../../../../../../../db/tables/subscribers";
import { checkSession } from "../../../../../../../functions/server/checkSession";
import { checkUserHasMonthlySubscription } from "../../../../../../../functions/server/user";
import { getEmailPreferenceForPrimaryEmail } from "../../../../../../../../db/tables/subscriber_email_preferences";

export const settingsTabSlugs = [
"edit-info",
"notifications",
"manage-account",
];

type Props = {
params: {
slug: string[] | undefined;
};
searchParams: {
nimbus_preview?: string;
};
};

export default async function SettingsPage({ searchParams }: Props) {
export default async function SettingsPage({ params, searchParams }: Props) {
const session = await getServerSession();

if (!session?.user?.subscriber?.id || !checkSession(session)) {
return redirect("/auth/logout");
}

const { slug } = params;
const defaultTab = settingsTabSlugs[0];
const activeTab = slug?.[0] ?? defaultTab;
// Only allow the tab slugs. Otherwise: Redirect to the default settings route.
if (
typeof slug !== "undefined" &&
(!settingsTabSlugs.includes(activeTab) || slug.length >= 2)
) {
return redirect(`/user/settings/${defaultTab}`);
}

const emailAddresses = await getUserEmails(session.user.subscriber.id);
const isMonthlySubscriber = await checkUserHasMonthlySubscription(
session.user,
Expand Down Expand Up @@ -112,6 +133,7 @@ export default async function SettingsPage({ searchParams }: Props) {
experimentData={experimentData}
lastScanDate={lastOneRepScan?.created_at}
isMonthlySubscriber={isMonthlySubscriber}
activeTab={activeTab as TabType}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

function SettingsPanelEditInfo() {
return <div>Edit info</div>;
return <div>Edit info content</div>;
}

export { SettingsPanelEditInfo };
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

function SettingsPanelManageAccount() {
return <div>Manage account</div>;
return <div>Manage account content</div>;
}

export { SettingsPanelManageAccount };
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

function SettingsPanelNotifications() {
return <div>Notifications</div>;
return <div>Set notifications content</div>;
}

export { SettingsPanelNotifications };
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function Panel(props: { type: string }) {
switch (props.type) {
case "edit-info":
return <SettingsPanelEditInfo />;
case "label-notification":
case "notifications":
return <SettingsPanelNotifications />;
case "manage-account":
return <SettingsPanelManageAccount />;
Expand Down

0 comments on commit b833165

Please sign in to comment.