diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.test.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.test.tsx index 2bc43a344bc..6b1c5e6d699 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.test.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.test.tsx @@ -20,6 +20,11 @@ import Meta, { DashboardNonUsNoBreaches, DashboardNonUsUnresolvedBreaches, DashboardNonUsResolvedBreaches, +} from "./DashboardNonUSUsers.stories"; +import { useTelemetry } from "../../../../../../hooks/useTelemetry"; +import { deleteAllCookies } from "../../../../../../functions/client/deleteAllCookies"; +import { defaultExperimentData } from "../../../../../../../telemetry/generated/nimbus/experiments"; +import { DashboardUsNoPremiumNoScanNoBreaches, DashboardUsNoPremiumNoScanUnresolvedBreaches, DashboardUsNoPremiumNoScanResolvedBreaches, @@ -33,6 +38,11 @@ import Meta, { DashboardUsNoPremiumResolvedScanNoBreaches, DashboardUsNoPremiumResolvedScanUnresolvedBreaches, DashboardUsNoPremiumResolvedScanResolvedBreaches, + DashboardUsNoPremiumScanInProgressNoBreaches, + DashboardUsNoPremiumScanInProgressUnresolvedBreaches, + DashboardUsNoPremiumScanInProgressResolvedBreaches, +} from "./DashboardUSUsers.stories"; +import { DashboardUsPremiumEmptyScanNoBreaches, DashboardUsPremiumEmptyScanUnresolvedBreaches, DashboardUsPremiumEmptyScanResolvedBreaches, @@ -42,18 +52,12 @@ import Meta, { DashboardUsPremiumResolvedScanNoBreaches, DashboardUsPremiumResolvedScanUnresolvedBreaches, DashboardUsPremiumResolvedScanResolvedBreaches, - DashboardUsNoPremiumScanInProgressNoBreaches, - DashboardUsNoPremiumScanInProgressUnresolvedBreaches, - DashboardUsNoPremiumScanInProgressResolvedBreaches, - DashboardUsPremiumScanInProgressNoBreaches, - DashboardUsPremiumScanInProgressUnresolvedBreaches, - DashboardUsPremiumScanInProgressResolvedBreaches, DashboardInvalidPremiumUserNoScanResolvedBreaches, DashboardUsPremiumManuallyResolvedScansNoBreaches, -} from "./Dashboard.stories"; -import { useTelemetry } from "../../../../../../hooks/useTelemetry"; -import { deleteAllCookies } from "../../../../../../functions/client/deleteAllCookies"; -import { defaultExperimentData } from "../../../../../../../telemetry/generated/nimbus/experiments"; + DashboardUsPremiumScanInProgressNoBreaches, + DashboardUsPremiumScanInProgressResolvedBreaches, + DashboardUsPremiumScanInProgressUnresolvedBreaches, +} from "./DashboardPlusUsers.stories"; jest.mock("next/navigation", () => ({ useRouter: jest.fn(), diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/DashboardNonUSUsers.stories.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/DashboardNonUSUsers.stories.tsx new file mode 100644 index 00000000000..02498a32694 --- /dev/null +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/DashboardNonUSUsers.stories.tsx @@ -0,0 +1,308 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import type { Meta, StoryObj } from "@storybook/react"; + +import { OnerepScanResultRow, OnerepScanRow } from "knex/types/tables"; +import { faker } from "@faker-js/faker"; +import { View as DashboardEl, TabType } from "./View"; +import { Shell } from "../../../../Shell"; +import { getL10n } from "../../../../../../functions/l10n/storybookAndJest"; +import { + createRandomScanResult, + createRandomBreach, + createUserWithPremiumSubscription, +} from "../../../../../../../apiMocks/mockData"; +import { SubscriberBreach } from "../../../../../../../utils/subscriberBreaches"; +import { LatestOnerepScanData } from "../../../../../../../db/tables/onerep_scans"; +import { CountryCodeProvider } from "../../../../../../../contextProviders/country-code"; +import { SessionProvider } from "../../../../../../../contextProviders/session"; +import { + ExperimentData, + defaultExperimentData, +} from "../../../../../../../telemetry/generated/nimbus/experiments"; +import { FeatureFlagName } from "../../../../../../../db/tables/featureFlags"; + +const brokerOptions = { + "no-scan": "No scan started", + empty: "No scan results", + unresolved: "With unresolved scan results", + resolved: "All scan results resolved", + "scan-in-progress": "Scan is in progress", + "manually-resolved": "Manually resolved", +}; +const breachOptions = { + empty: "No data breaches", + unresolved: "With unresolved data breaches", + resolved: "All data breaches resolved", +}; +type DashboardWrapperProps = ( + | { + countryCode: "us"; + brokers: keyof typeof brokerOptions; + premium: boolean; + } + | { + countryCode: "nl"; + } +) & { + brokers: keyof typeof brokerOptions; + breaches: keyof typeof breachOptions; + elapsedTimeInDaysSinceInitialScan?: number; + totalNumberOfPerformedScans?: number; + activeTab?: TabType; + enabledFeatureFlags?: FeatureFlagName[]; + experimentData?: ExperimentData; + hasFirstMonitoringScan?: boolean; + signInCount?: number; + autoOpenUpsellDialog?: boolean; +}; +const DashboardWrapper = (props: DashboardWrapperProps) => { + const mockedResolvedBreach: SubscriberBreach = createRandomBreach({ + dataClasses: [ + "email-addresses", + "ip-addresses", + "phone-numbers", + "passwords", + "pins", + "social-security-numbers", + "partial-credit-card-data", + "security-questions-and-answers", + ], + addedDate: new Date("2023-06-18T14:48:00.000Z"), + dataClassesEffected: [ + { "email-addresses": ["email1@gmail.com", "email2@gmail.com"] }, + { "ip-addresses": 1 }, + { "phone-numbers": 1 }, + { passwords: 1 }, + ], + isResolved: true, + }); + + const mockedUnresolvedBreach: SubscriberBreach = createRandomBreach({ + dataClasses: ["email-addresses", "ip-addresses", "phone-numbers"], + addedDate: new Date("2023-06-18T14:48:00.000Z"), + dataClassesEffected: [ + { "email-addresses": ["email1@gmail.com", "email2@gmail.com"] }, + { "ip-addresses": 1 }, + ], + isResolved: false, + }); + + let breaches: SubscriberBreach[] = []; + if (props.breaches === "resolved") { + breaches = [mockedResolvedBreach]; + } + if (props.breaches === "unresolved") { + breaches = [mockedResolvedBreach, mockedUnresolvedBreach]; + } + + const mockedScan: OnerepScanRow = { + created_at: new Date(Date.UTC(1998, 2, 31)), + updated_at: new Date(Date.UTC(1998, 2, 31)), + id: 0, + onerep_profile_id: 0, + onerep_scan_id: 0, + onerep_scan_reason: "initial", + onerep_scan_status: "finished", + }; + + const mockedScanInProgress: OnerepScanRow = { + ...mockedScan, + onerep_scan_status: "in_progress", + }; + + const mockedInProgressScanResults: OnerepScanResultRow[] = [ + createRandomScanResult({ status: "removed", manually_resolved: false }), + createRandomScanResult({ + status: "waiting_for_verification", + manually_resolved: false, + }), + createRandomScanResult({ + status: "optout_in_progress", + manually_resolved: false, + }), + ]; + + const mockedAllResolvedScanResults: OnerepScanResultRow[] = [ + createRandomScanResult({ status: "removed", manually_resolved: false }), + createRandomScanResult({ status: "removed", manually_resolved: false }), + ]; + + const mockedUnresolvedScanResults: OnerepScanResultRow[] = [ + ...mockedInProgressScanResults, + createRandomScanResult({ status: "new", manually_resolved: false }), + createRandomScanResult({ status: "new", manually_resolved: false }), + createRandomScanResult({ status: "new", manually_resolved: true }), + ]; + + const mockedManuallyResolvedScanResults: OnerepScanResultRow[] = [ + createRandomScanResult({ status: "new", manually_resolved: true }), + createRandomScanResult({ + status: "waiting_for_verification", + manually_resolved: true, + }), + createRandomScanResult({ + status: "optout_in_progress", + manually_resolved: true, + }), + createRandomScanResult({ status: "removed", manually_resolved: true }), + ]; + + const scanData: LatestOnerepScanData = { scan: null, results: [] }; + let scanCount = 0; + + if (props.countryCode === "us") { + if (props.brokers && props.brokers !== "no-scan") { + const scanInProgress = props.brokers === "scan-in-progress"; + scanData.scan = scanInProgress ? mockedScanInProgress : mockedScan; + + if (scanInProgress) { + scanCount = 1; + } + if (props.brokers === "resolved") { + scanData.results = mockedAllResolvedScanResults; + } + if (props.brokers === "unresolved") { + scanData.results = mockedUnresolvedScanResults; + } + + if (props.brokers === "manually-resolved") { + scanData.results = mockedManuallyResolvedScanResults; + } + } + } + + const user = createUserWithPremiumSubscription(); + if ((props.countryCode !== "us" || !props.premium) && user.fxa) { + user.fxa.subscriptions = []; + } + + const mockedSession = { + expires: new Date().toISOString(), + user: user, + }; + + const mockedRemovalTimeEstimates = scanData.results + .map((scan) => ({ + d: scan.data_broker, + t: faker.number.float({ min: 0, max: 200 }), + })) + .filter(() => Math.random() < 0.1); + + return ( + + + + + + + + ); +}; + +const meta: Meta = { + title: "Pages/Logged in/Dashboard/Non US User", + component: DashboardWrapper, + argTypes: { + brokers: { + options: Object.keys(brokerOptions), + description: "Scan results", + control: { + type: "radio", + labels: brokerOptions, + }, + }, + breaches: { + options: Object.keys(breachOptions), + control: { + type: "radio", + labels: breachOptions, + }, + }, + elapsedTimeInDaysSinceInitialScan: { + name: "Days since initial scan", + control: { + type: "number", + }, + }, + hasFirstMonitoringScan: { + name: "Has first monitoring scan", + control: { + type: "boolean", + }, + }, + signInCount: { + name: "Sign-in count", + control: { + type: "number", + }, + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const DashboardNonUsNoBreaches: Story = { + name: "Non-US user, with 0 breaches", + args: { + countryCode: "nl", + breaches: "empty", + }, +}; + +export const DashboardNonUsUnresolvedBreaches: Story = { + name: "Non-US user, with unresolved breaches", + args: { + countryCode: "nl", + breaches: "unresolved", + }, +}; + +export const DashboardNonUsResolvedBreaches: Story = { + name: "Non-US user, with all breaches resolved", + args: { + countryCode: "nl", + breaches: "resolved", + }, +}; diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.stories.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/DashboardPlusUsers.stories.tsx similarity index 76% rename from src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.stories.tsx rename to src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/DashboardPlusUsers.stories.tsx index edd1db69390..22310ae744c 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.stories.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/DashboardPlusUsers.stories.tsx @@ -241,7 +241,7 @@ const DashboardWrapper = (props: DashboardWrapperProps) => { }; const meta: Meta = { - title: "Pages/Logged in/Dashboard", + title: "Pages/Logged in/Dashboard/US User/Plus", component: DashboardWrapper, argTypes: { brokers: { @@ -279,164 +279,10 @@ const meta: Meta = { }, }, }; + export default meta; type Story = StoryObj; -export const DashboardNonUsNoBreaches: Story = { - name: "Non-US user, with 0 breaches", - args: { - countryCode: "nl", - breaches: "empty", - }, -}; - -export const DashboardNonUsUnresolvedBreaches: Story = { - name: "Non-US user, with unresolved breaches", - args: { - countryCode: "nl", - breaches: "unresolved", - }, -}; - -export const DashboardNonUsResolvedBreaches: Story = { - name: "Non-US user, with all breaches resolved", - args: { - countryCode: "nl", - breaches: "resolved", - }, -}; - -export const DashboardUsNoPremiumNoScanNoBreaches: Story = { - name: "US user, without Premium, without scan, with 0 breaches", - args: { - countryCode: "us", - premium: false, - breaches: "empty", - brokers: "no-scan", - }, -}; - -export const DashboardUsNoPremiumNoScanUnresolvedBreaches: Story = { - name: "US user, without Premium, without scan, with unresolved breaches", - args: { - countryCode: "us", - premium: false, - breaches: "unresolved", - brokers: "no-scan", - }, -}; - -export const DashboardUsNoPremiumNoScanResolvedBreaches: Story = { - name: "US user, without Premium, without scan, with all breaches resolved", - args: { - countryCode: "us", - premium: false, - breaches: "resolved", - brokers: "no-scan", - }, -}; - -export const DashboardUsNoPremiumNoScanNoBreachesScanLimitReached: Story = { - name: "US user, without Premium, without scan, with 0 breaches, Scan limit reached", - args: { - countryCode: "us", - premium: false, - breaches: "empty", - brokers: "no-scan", - totalNumberOfPerformedScans: 280000, - }, -}; - -export const DashboardUsNoPremiumEmptyScanNoBreaches: Story = { - name: "US user, without Premium, with 0 scan results, with 0 breaches", - args: { - countryCode: "us", - premium: false, - breaches: "empty", - brokers: "empty", - }, -}; - -export const DashboardUsNoPremiumEmptyScanUnresolvedBreaches: Story = { - name: "US user, without Premium, with 0 scan results, with unresolved breaches", - args: { - countryCode: "us", - premium: false, - breaches: "unresolved", - brokers: "empty", - }, -}; - -export const DashboardUsNoPremiumEmptyScanResolvedBreaches: Story = { - name: "US user, without Premium, with 0 scan results, with all breaches resolved", - args: { - countryCode: "us", - premium: false, - breaches: "resolved", - brokers: "empty", - }, -}; - -export const DashboardUsNoPremiumUnresolvedScanNoBreaches: Story = { - name: "US user, without Premium, with unresolved scan results, with 0 breaches", - args: { - countryCode: "us", - premium: false, - breaches: "empty", - brokers: "unresolved", - }, -}; - -export const DashboardUsNoPremiumUnresolvedScanUnresolvedBreaches: Story = { - name: "US user, without Premium, with unresolved scan results, with unresolved breaches", - args: { - countryCode: "us", - premium: false, - breaches: "unresolved", - brokers: "unresolved", - }, -}; - -export const DashboardUsNoPremiumUnresolvedScanResolvedBreaches: Story = { - name: "US user, without Premium, with unresolved scan results, with all breaches resolved", - args: { - countryCode: "us", - premium: false, - breaches: "resolved", - brokers: "unresolved", - }, -}; - -export const DashboardUsNoPremiumResolvedScanNoBreaches: Story = { - name: "US user, without Premium, with all scan results resolved, with 0 breaches", - args: { - countryCode: "us", - premium: false, - breaches: "empty", - brokers: "resolved", - }, -}; - -export const DashboardUsNoPremiumResolvedScanUnresolvedBreaches: Story = { - name: "US user, without Premium, with all scan results resolved, with unresolved breaches", - args: { - countryCode: "us", - premium: false, - breaches: "unresolved", - brokers: "resolved", - }, -}; - -export const DashboardUsNoPremiumResolvedScanResolvedBreaches: Story = { - name: "US user, without Premium, with all scan results resolved, with all breaches resolved", - args: { - countryCode: "us", - premium: false, - breaches: "resolved", - brokers: "resolved", - }, -}; - export const DashboardUsPremiumEmptyScanNoBreaches: Story = { name: "US user, with Premium, with 0 scan results, with 0 breaches", args: { diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/DashboardUSUsers.stories.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/DashboardUSUsers.stories.tsx new file mode 100644 index 00000000000..2aa3d652be2 --- /dev/null +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/DashboardUSUsers.stories.tsx @@ -0,0 +1,445 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import type { Meta, StoryObj } from "@storybook/react"; + +import { OnerepScanResultRow, OnerepScanRow } from "knex/types/tables"; +import { faker } from "@faker-js/faker"; +import { View as DashboardEl, TabType } from "./View"; +import { Shell } from "../../../../Shell"; +import { getL10n } from "../../../../../../functions/l10n/storybookAndJest"; +import { + createRandomScanResult, + createRandomBreach, + createUserWithPremiumSubscription, +} from "../../../../../../../apiMocks/mockData"; +import { SubscriberBreach } from "../../../../../../../utils/subscriberBreaches"; +import { LatestOnerepScanData } from "../../../../../../../db/tables/onerep_scans"; +import { CountryCodeProvider } from "../../../../../../../contextProviders/country-code"; +import { SessionProvider } from "../../../../../../../contextProviders/session"; +import { + ExperimentData, + defaultExperimentData, +} from "../../../../../../../telemetry/generated/nimbus/experiments"; +import { FeatureFlagName } from "../../../../../../../db/tables/featureFlags"; + +const brokerOptions = { + "no-scan": "No scan started", + empty: "No scan results", + unresolved: "With unresolved scan results", + resolved: "All scan results resolved", + "scan-in-progress": "Scan is in progress", + "manually-resolved": "Manually resolved", +}; +const breachOptions = { + empty: "No data breaches", + unresolved: "With unresolved data breaches", + resolved: "All data breaches resolved", +}; +type DashboardWrapperProps = ( + | { + countryCode: "us"; + brokers: keyof typeof brokerOptions; + premium: boolean; + } + | { + countryCode: "nl"; + } +) & { + brokers: keyof typeof brokerOptions; + breaches: keyof typeof breachOptions; + elapsedTimeInDaysSinceInitialScan?: number; + totalNumberOfPerformedScans?: number; + activeTab?: TabType; + enabledFeatureFlags?: FeatureFlagName[]; + experimentData?: ExperimentData; + hasFirstMonitoringScan?: boolean; + signInCount?: number; + autoOpenUpsellDialog?: boolean; +}; +const DashboardWrapper = (props: DashboardWrapperProps) => { + const mockedResolvedBreach: SubscriberBreach = createRandomBreach({ + dataClasses: [ + "email-addresses", + "ip-addresses", + "phone-numbers", + "passwords", + "pins", + "social-security-numbers", + "partial-credit-card-data", + "security-questions-and-answers", + ], + addedDate: new Date("2023-06-18T14:48:00.000Z"), + dataClassesEffected: [ + { "email-addresses": ["email1@gmail.com", "email2@gmail.com"] }, + { "ip-addresses": 1 }, + { "phone-numbers": 1 }, + { passwords: 1 }, + ], + isResolved: true, + }); + + const mockedUnresolvedBreach: SubscriberBreach = createRandomBreach({ + dataClasses: ["email-addresses", "ip-addresses", "phone-numbers"], + addedDate: new Date("2023-06-18T14:48:00.000Z"), + dataClassesEffected: [ + { "email-addresses": ["email1@gmail.com", "email2@gmail.com"] }, + { "ip-addresses": 1 }, + ], + isResolved: false, + }); + + let breaches: SubscriberBreach[] = []; + if (props.breaches === "resolved") { + breaches = [mockedResolvedBreach]; + } + if (props.breaches === "unresolved") { + breaches = [mockedResolvedBreach, mockedUnresolvedBreach]; + } + + const mockedScan: OnerepScanRow = { + created_at: new Date(Date.UTC(1998, 2, 31)), + updated_at: new Date(Date.UTC(1998, 2, 31)), + id: 0, + onerep_profile_id: 0, + onerep_scan_id: 0, + onerep_scan_reason: "initial", + onerep_scan_status: "finished", + }; + + const mockedScanInProgress: OnerepScanRow = { + ...mockedScan, + onerep_scan_status: "in_progress", + }; + + const mockedInProgressScanResults: OnerepScanResultRow[] = [ + createRandomScanResult({ status: "removed", manually_resolved: false }), + createRandomScanResult({ + status: "waiting_for_verification", + manually_resolved: false, + }), + createRandomScanResult({ + status: "optout_in_progress", + manually_resolved: false, + }), + ]; + + const mockedAllResolvedScanResults: OnerepScanResultRow[] = [ + createRandomScanResult({ status: "removed", manually_resolved: false }), + createRandomScanResult({ status: "removed", manually_resolved: false }), + ]; + + const mockedUnresolvedScanResults: OnerepScanResultRow[] = [ + ...mockedInProgressScanResults, + createRandomScanResult({ status: "new", manually_resolved: false }), + createRandomScanResult({ status: "new", manually_resolved: false }), + createRandomScanResult({ status: "new", manually_resolved: true }), + ]; + + const mockedManuallyResolvedScanResults: OnerepScanResultRow[] = [ + createRandomScanResult({ status: "new", manually_resolved: true }), + createRandomScanResult({ + status: "waiting_for_verification", + manually_resolved: true, + }), + createRandomScanResult({ + status: "optout_in_progress", + manually_resolved: true, + }), + createRandomScanResult({ status: "removed", manually_resolved: true }), + ]; + + const scanData: LatestOnerepScanData = { scan: null, results: [] }; + let scanCount = 0; + + if (props.countryCode === "us") { + if (props.brokers && props.brokers !== "no-scan") { + const scanInProgress = props.brokers === "scan-in-progress"; + scanData.scan = scanInProgress ? mockedScanInProgress : mockedScan; + + if (scanInProgress) { + scanCount = 1; + } + if (props.brokers === "resolved") { + scanData.results = mockedAllResolvedScanResults; + } + if (props.brokers === "unresolved") { + scanData.results = mockedUnresolvedScanResults; + } + + if (props.brokers === "manually-resolved") { + scanData.results = mockedManuallyResolvedScanResults; + } + } + } + + const user = createUserWithPremiumSubscription(); + if ((props.countryCode !== "us" || !props.premium) && user.fxa) { + user.fxa.subscriptions = []; + } + + const mockedSession = { + expires: new Date().toISOString(), + user: user, + }; + + const mockedRemovalTimeEstimates = scanData.results + .map((scan) => ({ + d: scan.data_broker, + t: faker.number.float({ min: 0, max: 200 }), + })) + .filter(() => Math.random() < 0.1); + + return ( + + + + + + + + ); +}; + +const meta: Meta = { + title: "Pages/Logged in/Dashboard/US User/No Plus", + component: DashboardWrapper, + argTypes: { + brokers: { + options: Object.keys(brokerOptions), + description: "Scan results", + control: { + type: "radio", + labels: brokerOptions, + }, + }, + breaches: { + options: Object.keys(breachOptions), + control: { + type: "radio", + labels: breachOptions, + }, + }, + elapsedTimeInDaysSinceInitialScan: { + name: "Days since initial scan", + control: { + type: "number", + }, + }, + hasFirstMonitoringScan: { + name: "Has first monitoring scan", + control: { + type: "boolean", + }, + }, + signInCount: { + name: "Sign-in count", + control: { + type: "number", + }, + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const DashboardUsNoPremiumNoScanNoBreaches: Story = { + name: "US user, without Premium, without scan, with 0 breaches", + args: { + countryCode: "us", + premium: false, + breaches: "empty", + brokers: "no-scan", + }, +}; + +export const DashboardUsNoPremiumNoScanUnresolvedBreaches: Story = { + name: "US user, without Premium, without scan, with unresolved breaches", + args: { + countryCode: "us", + premium: false, + breaches: "unresolved", + brokers: "no-scan", + }, +}; + +export const DashboardUsNoPremiumNoScanResolvedBreaches: Story = { + name: "US user, without Premium, without scan, with all breaches resolved", + args: { + countryCode: "us", + premium: false, + breaches: "resolved", + brokers: "no-scan", + }, +}; + +export const DashboardUsNoPremiumNoScanNoBreachesScanLimitReached: Story = { + name: "US user, without Premium, without scan, with 0 breaches, Scan limit reached", + args: { + countryCode: "us", + premium: false, + breaches: "empty", + brokers: "no-scan", + totalNumberOfPerformedScans: 280000, + }, +}; + +export const DashboardUsNoPremiumEmptyScanNoBreaches: Story = { + name: "US user, without Premium, with 0 scan results, with 0 breaches", + args: { + countryCode: "us", + premium: false, + breaches: "empty", + brokers: "empty", + }, +}; + +export const DashboardUsNoPremiumEmptyScanUnresolvedBreaches: Story = { + name: "US user, without Premium, with 0 scan results, with unresolved breaches", + args: { + countryCode: "us", + premium: false, + breaches: "unresolved", + brokers: "empty", + }, +}; + +export const DashboardUsNoPremiumEmptyScanResolvedBreaches: Story = { + name: "US user, without Premium, with 0 scan results, with all breaches resolved", + args: { + countryCode: "us", + premium: false, + breaches: "resolved", + brokers: "empty", + }, +}; + +export const DashboardUsNoPremiumUnresolvedScanNoBreaches: Story = { + name: "US user, without Premium, with unresolved scan results, with 0 breaches", + args: { + countryCode: "us", + premium: false, + breaches: "empty", + brokers: "unresolved", + }, +}; + +export const DashboardUsNoPremiumUnresolvedScanUnresolvedBreaches: Story = { + name: "US user, without Premium, with unresolved scan results, with unresolved breaches", + args: { + countryCode: "us", + premium: false, + breaches: "unresolved", + brokers: "unresolved", + }, +}; + +export const DashboardUsNoPremiumUnresolvedScanResolvedBreaches: Story = { + name: "US user, without Premium, with unresolved scan results, with all breaches resolved", + args: { + countryCode: "us", + premium: false, + breaches: "resolved", + brokers: "unresolved", + }, +}; + +export const DashboardUsNoPremiumResolvedScanNoBreaches: Story = { + name: "US user, without Premium, with all scan results resolved, with 0 breaches", + args: { + countryCode: "us", + premium: false, + breaches: "empty", + brokers: "resolved", + }, +}; + +export const DashboardUsNoPremiumResolvedScanUnresolvedBreaches: Story = { + name: "US user, without Premium, with all scan results resolved, with unresolved breaches", + args: { + countryCode: "us", + premium: false, + breaches: "unresolved", + brokers: "resolved", + }, +}; + +export const DashboardUsNoPremiumResolvedScanResolvedBreaches: Story = { + name: "US user, without Premium, with all scan results resolved, with all breaches resolved", + args: { + countryCode: "us", + premium: false, + breaches: "resolved", + brokers: "resolved", + }, +}; + +export const DashboardUsNoPremiumScanInProgressNoBreaches: Story = { + name: "US user, without Premium, scan in progress, with no breaches", + args: { + countryCode: "us", + premium: false, + breaches: "empty", + brokers: "scan-in-progress", + }, +}; + +export const DashboardUsNoPremiumScanInProgressUnresolvedBreaches: Story = { + name: "US user, without Premium, scan in progress, with unresolved breaches", + args: { + countryCode: "us", + premium: false, + breaches: "unresolved", + brokers: "scan-in-progress", + }, +}; + +export const DashboardUsNoPremiumScanInProgressResolvedBreaches: Story = { + name: "US user, without Premium, scan in progress, with resolved breaches", + args: { + countryCode: "us", + premium: false, + breaches: "resolved", + brokers: "scan-in-progress", + }, +}; diff --git a/src/app/(proper_react)/(redesign)/(public)/MobileShell.stories.ts b/src/app/(proper_react)/(redesign)/(public)/MobileShell.stories.ts new file mode 100644 index 00000000000..cc0dda1dafe --- /dev/null +++ b/src/app/(proper_react)/(redesign)/(public)/MobileShell.stories.ts @@ -0,0 +1,45 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { Session } from "next-auth"; +import { SerializedSubscriber } from "../../../../next-auth"; + +import type { Meta, StoryObj } from "@storybook/react"; +import { MobileShell } from "../MobileShell"; + +function createUser(): Session["user"] { + return { + email: "example@example.com", + fxa: { + locale: "us", + twoFactorAuthentication: false, + metricsEnabled: false, + avatar: "https://profile.stage.mozaws.net/v1/avatar/e", + avatarDefault: true, + subscriptions: ["monitor"], + }, + subscriber: { + id: 42, + } as SerializedSubscriber, + }; +} + +const mockedSession = { + expires: new Date().toISOString(), + user: createUser(), +}; + +const meta: Meta = { + title: "Layout/Mobile Shell", + component: MobileShell, +}; +export default meta; +type Story = StoryObj; + +export const MobileShellStory: Story = { + args: { + countryCode: "us", + session: mockedSession, + }, +}; diff --git a/src/app/(proper_react)/(redesign)/(public)/PublicShell.stories.ts b/src/app/(proper_react)/(redesign)/(public)/PublicShell.stories.ts new file mode 100644 index 00000000000..87dd3f7ae6f --- /dev/null +++ b/src/app/(proper_react)/(redesign)/(public)/PublicShell.stories.ts @@ -0,0 +1,22 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import type { Meta, StoryObj } from "@storybook/react"; + +import { PublicShell } from "./PublicShell"; +import { getL10n } from "../../../functions/l10n/storybookAndJest"; + +const meta: Meta = { + title: "Layout/Public Shell", + component: PublicShell, +}; +export default meta; +type Story = StoryObj; + +export const PublicShellStory: Story = { + args: { + countryCode: "us", + l10n: getL10n("en"), + }, +}; diff --git a/src/app/components/client/exposure_card/ExposureCard.stories.tsx b/src/app/components/client/exposure_card/ExposureCard.stories.tsx index 12217af9483..4aac589328e 100644 --- a/src/app/components/client/exposure_card/ExposureCard.stories.tsx +++ b/src/app/components/client/exposure_card/ExposureCard.stories.tsx @@ -13,7 +13,7 @@ import { import { defaultExperimentData } from "../../../../telemetry/generated/nimbus/experiments"; const meta: Meta = { - title: "ExposureCard", + title: "Dashboard/Exposures/Exposure Card", component: ExposureCard, tags: ["autodocs"], args: { diff --git a/src/app/components/client/stories/Button.stories.ts b/src/app/components/client/stories/Button.stories.ts index c3c2e8f36d4..5f03aca8ef9 100644 --- a/src/app/components/client/stories/Button.stories.ts +++ b/src/app/components/client/stories/Button.stories.ts @@ -8,7 +8,7 @@ import { Button } from "../Button"; // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction const meta: Meta = { - title: "Button", + title: "Design Systems/Atoms/Button", component: Button, }; export default meta; diff --git a/src/app/components/client/stories/Chart.stories.ts b/src/app/components/client/stories/Chart.stories.ts index e1748c19058..a8fed6811ed 100644 --- a/src/app/components/client/stories/Chart.stories.ts +++ b/src/app/components/client/stories/Chart.stories.ts @@ -8,7 +8,7 @@ import { DoughnutChart } from "../Chart"; // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction const meta: Meta = { - title: "Charts", + title: "Dashboard/TopBanner/Charts", component: DoughnutChart, }; export default meta; diff --git a/src/app/components/client/stories/Checkbox.stories.ts b/src/app/components/client/stories/Checkbox.stories.ts new file mode 100644 index 00000000000..831c9426b6d --- /dev/null +++ b/src/app/components/client/stories/Checkbox.stories.ts @@ -0,0 +1,71 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import type { Meta, StoryObj } from "@storybook/react"; + +import { Button } from "../Button"; + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction +const meta: Meta = { + title: "Design Systems/Atoms/Checkbox", + component: Button, +}; +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: { + variant: "primary", + children: "Button", + destructive: false, + small: false, + }, +}; + +export const Secondary: Story = { + args: { + variant: "secondary", + children: "Button", + }, +}; + +export const PrimarySmall: Story = { + args: { + variant: "primary", + children: "Button", + small: true, + }, +}; + +export const PrimaryWide: Story = { + args: { + variant: "primary", + children: "Button", + wide: true, + }, +}; + +export const SecondarySmall: Story = { + args: { + variant: "secondary", + children: "Button", + small: true, + }, +}; + +export const PrimaryLink: Story = { + args: { + variant: "primary", + children: "Button", + href: "/", + }, +}; + +export const SecondaryLink: Story = { + args: { + variant: "secondary", + children: "Button", + href: "/", + }, +}; diff --git a/src/app/components/client/stories/ComboBox.stories.tsx b/src/app/components/client/stories/ComboBox.stories.tsx index 2a5ed43d24c..14e33a10bf3 100644 --- a/src/app/components/client/stories/ComboBox.stories.tsx +++ b/src/app/components/client/stories/ComboBox.stories.tsx @@ -20,7 +20,7 @@ const items: Array = [ ]; const meta: Meta = { - title: "ComboBox", + title: "Design Systems/Atoms/ComboBox", component: ComboBox, }; export default meta; diff --git a/src/app/components/client/stories/CsatSurvey.stories.ts b/src/app/components/client/stories/CsatSurvey.stories.ts index 3e5453db77c..889fde8d679 100644 --- a/src/app/components/client/stories/CsatSurvey.stories.ts +++ b/src/app/components/client/stories/CsatSurvey.stories.ts @@ -9,7 +9,7 @@ import { createUserWithPremiumSubscription } from "../../../../apiMocks/mockData import { defaultExperimentData } from "../../../../telemetry/generated/nimbus/experiments"; const meta: Meta = { - title: "CsatSurvey", + title: "Misc/CsatSurvey", component: CsatSurvey, }; export default meta; diff --git a/src/app/components/client/stories/ExposuresFilter.stories.ts b/src/app/components/client/stories/ExposuresFilter.stories.ts index a7c0de228db..c64ed7a806c 100644 --- a/src/app/components/client/stories/ExposuresFilter.stories.ts +++ b/src/app/components/client/stories/ExposuresFilter.stories.ts @@ -7,7 +7,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { ExposuresFilter, FilterState } from "../ExposuresFilter"; const meta: Meta = { - title: "ExposuresFilter", + title: "Dashboard/Exposures/FilterBar", component: ExposuresFilter, }; export default meta; diff --git a/src/app/components/client/stories/InputField.stories.ts b/src/app/components/client/stories/InputField.stories.ts index 402684871c9..59e1a7666a1 100644 --- a/src/app/components/client/stories/InputField.stories.ts +++ b/src/app/components/client/stories/InputField.stories.ts @@ -7,7 +7,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { InputField } from "../InputField"; const meta: Meta = { - title: "InputField", + title: "Design Systems/Molecules/Input Field", component: InputField, }; export default meta; diff --git a/src/app/components/client/stories/PetitionBanner.stories.ts b/src/app/components/client/stories/PetitionBanner.stories.ts index 5a46986b6cb..177f13216ce 100644 --- a/src/app/components/client/stories/PetitionBanner.stories.ts +++ b/src/app/components/client/stories/PetitionBanner.stories.ts @@ -7,7 +7,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { PetitionBanner } from "../PetitionBanner"; const meta: Meta = { - title: "PetitionBanner", + title: "Misc/PetitionBanner", component: PetitionBanner, }; export default meta; diff --git a/src/app/components/client/stories/ProgressBar.stories.tsx b/src/app/components/client/stories/ProgressBar.stories.tsx index 64b1057e14f..9f065e91cf1 100644 --- a/src/app/components/client/stories/ProgressBar.stories.tsx +++ b/src/app/components/client/stories/ProgressBar.stories.tsx @@ -21,7 +21,7 @@ const ProgressBarDemo = (props: ProgressBarProps) => { // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction const meta: Meta = { - title: "Progress bar", + title: "Welcome Scan/ProgressBar", component: ProgressBarDemo, }; export default meta; diff --git a/src/app/components/client/stories/ProgressCard.stories.ts b/src/app/components/client/stories/ProgressCard.stories.ts index 4ca1cd80dc6..ddff6f5663d 100644 --- a/src/app/components/client/stories/ProgressCard.stories.ts +++ b/src/app/components/client/stories/ProgressCard.stories.ts @@ -8,7 +8,7 @@ import { ProgressCard } from "../ProgressCard"; // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction const meta: Meta = { - title: "ProgressCard", + title: "Dashboard/Top Banner/Progress Infographic", component: ProgressCard, }; export default meta; diff --git a/src/app/components/client/stories/Radio.stories.ts b/src/app/components/client/stories/Radio.stories.ts new file mode 100644 index 00000000000..8fb77141094 --- /dev/null +++ b/src/app/components/client/stories/Radio.stories.ts @@ -0,0 +1,71 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import type { Meta, StoryObj } from "@storybook/react"; + +import { Button } from "../Button"; + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction +const meta: Meta = { + title: "Design Systems/Atoms/Radio", + component: Button, +}; +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: { + variant: "primary", + children: "Button", + destructive: false, + small: false, + }, +}; + +export const Secondary: Story = { + args: { + variant: "secondary", + children: "Button", + }, +}; + +export const PrimarySmall: Story = { + args: { + variant: "primary", + children: "Button", + small: true, + }, +}; + +export const PrimaryWide: Story = { + args: { + variant: "primary", + children: "Button", + wide: true, + }, +}; + +export const SecondarySmall: Story = { + args: { + variant: "secondary", + children: "Button", + small: true, + }, +}; + +export const PrimaryLink: Story = { + args: { + variant: "primary", + children: "Button", + href: "/", + }, +}; + +export const SecondaryLink: Story = { + args: { + variant: "secondary", + children: "Button", + href: "/", + }, +}; diff --git a/src/app/components/client/stories/TabList.stories.ts b/src/app/components/client/stories/TabList.stories.ts index f2d18fd1907..d3d316e2b04 100644 --- a/src/app/components/client/stories/TabList.stories.ts +++ b/src/app/components/client/stories/TabList.stories.ts @@ -7,7 +7,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { TabList } from "../TabList"; const meta: Meta = { - title: "TabList", + title: "Design Systems/Molecules/TabList", component: TabList, }; export default meta; diff --git a/src/app/components/client/stories/UpsellCta.stories.tsx b/src/app/components/client/stories/UpsellCta.stories.tsx index 2cc9c70536d..801480cdf9e 100644 --- a/src/app/components/client/stories/UpsellCta.stories.tsx +++ b/src/app/components/client/stories/UpsellCta.stories.tsx @@ -58,7 +58,7 @@ const UpsellCtaWrapper = (props: UpsellCtaWrapperProps) => { }; const meta: Meta = { - title: "Upsell CTA", + title: "Design Systems/Atoms/Misc/Upsell CTA", component: UpsellCtaWrapper, }; export default meta; diff --git a/src/app/components/client/toolbar/AppPicker.stories.ts b/src/app/components/client/toolbar/AppPicker.stories.ts index 890875b7510..96b84c99ea8 100644 --- a/src/app/components/client/toolbar/AppPicker.stories.ts +++ b/src/app/components/client/toolbar/AppPicker.stories.ts @@ -6,7 +6,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { AppPicker } from "./AppPicker"; const meta: Meta = { - title: "Toolbar", + title: "Layout/Navigation/Bento App Picker", component: AppPicker, }; diff --git a/src/app/components/client/toolbar/UserMenu.stories.ts b/src/app/components/client/toolbar/UserMenu.stories.ts index 48cc9d057cb..5cee50c7349 100644 --- a/src/app/components/client/toolbar/UserMenu.stories.ts +++ b/src/app/components/client/toolbar/UserMenu.stories.ts @@ -6,7 +6,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { UserMenu } from "./UserMenu"; const meta: Meta = { - title: "Toolbar", + title: "Layout/Navigation/Toolbar", component: UserMenu, }; export default meta; diff --git a/src/app/components/server/stories/StatusPill.stories.ts b/src/app/components/server/stories/StatusPill.stories.ts index 7d78adf207f..e8a9b125f46 100644 --- a/src/app/components/server/stories/StatusPill.stories.ts +++ b/src/app/components/server/stories/StatusPill.stories.ts @@ -8,7 +8,7 @@ import { StatusPill } from "../StatusPill"; // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction const meta: Meta = { - title: "Status Pill", + title: "Design Systems/Atoms/Pill", component: StatusPill, }; export default meta;