diff --git a/apps/dashboard/.storybook/main.ts b/apps/dashboard/.storybook/main.ts index 255aac67d66..9bda0c51ed1 100644 --- a/apps/dashboard/.storybook/main.ts +++ b/apps/dashboard/.storybook/main.ts @@ -27,5 +27,8 @@ const config: StorybookConfig = { }, }, staticDirs: ["../public"], + features: { + experimentalRSC: true, + }, }; export default config; diff --git a/apps/dashboard/src/@/components/blocks/code-segment.client.tsx b/apps/dashboard/src/@/components/blocks/code-segment.client.tsx index 594a088bb1d..b2b6b76f2e2 100644 --- a/apps/dashboard/src/@/components/blocks/code-segment.client.tsx +++ b/apps/dashboard/src/@/components/blocks/code-segment.client.tsx @@ -96,7 +96,6 @@ export const CodeSegment: React.FC = ({ onClick: () => setEnvironment(env.environment), isActive: activeEnvironment === env.environment, name: env.title, - isEnabled: true, }))} tabClassName="text-sm gap-2 !text-sm" tabIconClassName="size-4" diff --git a/apps/dashboard/src/@/components/ui/DatePickerWithRange.tsx b/apps/dashboard/src/@/components/ui/DatePickerWithRange.tsx index 793e1964fae..22910ee9e67 100644 --- a/apps/dashboard/src/@/components/ui/DatePickerWithRange.tsx +++ b/apps/dashboard/src/@/components/ui/DatePickerWithRange.tsx @@ -91,13 +91,11 @@ export function DatePickerWithRange(props: { name: "From", onClick: () => setScreen("from"), isActive: screen === "from", - isEnabled: true, }, { name: "To", onClick: () => setScreen("to"), isActive: screen === "to", - isEnabled: true, }, ]} /> diff --git a/apps/dashboard/src/@/components/ui/tabs.tsx b/apps/dashboard/src/@/components/ui/tabs.tsx index 0d2c64ee582..ffdd1e036ee 100644 --- a/apps/dashboard/src/@/components/ui/tabs.tsx +++ b/apps/dashboard/src/@/components/ui/tabs.tsx @@ -79,7 +79,7 @@ export function TabButtons(props: { name: React.ReactNode; onClick: () => void; isActive: boolean; - isEnabled?: boolean; + isDisabled?: boolean; icon?: React.FC<{ className?: string }>; }[]; tabClassName?: string; @@ -119,11 +119,11 @@ export function TabButtons(props: { "relative inline-flex h-auto items-center gap-1.5 rounded-lg px-2 font-medium text-sm hover:bg-accent lg:px-3 lg:text-base", !tab.isActive && "text-muted-foreground hover:text-foreground", - !tab.isEnabled && "cursor-not-allowed opacity-50", + tab.isDisabled && "cursor-not-allowed opacity-50", props.tabClassName, tab.isActive && props.activeTabClassName, )} - onClick={tab.isEnabled ? tab.onClick : undefined} + onClick={!tab.isDisabled ? tab.onClick : undefined} > {tab.icon && ( diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-button.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-button.tsx index d30ecc2e13d..5e3ad7cc488 100644 --- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-button.tsx +++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-button.tsx @@ -71,7 +71,6 @@ export const CreateListingButton: React.FC = ({ name: mode, isActive: mode === listingMode, onClick: () => setListingMode(mode), - isEnabled: true, }))} tabClassName="text-sm gap-2 !text-sm" tabContainerClassName="gap-0.5" diff --git a/apps/dashboard/src/app/account/contracts/_components/GetStartedWithContractsDeploy.tsx b/apps/dashboard/src/app/account/contracts/_components/GetStartedWithContractsDeploy.tsx index 66dc62d0a69..818674d113c 100644 --- a/apps/dashboard/src/app/account/contracts/_components/GetStartedWithContractsDeploy.tsx +++ b/apps/dashboard/src/app/account/contracts/_components/GetStartedWithContractsDeploy.tsx @@ -100,7 +100,6 @@ const DeployOptions = (props: { key, name: value.title, isActive: activeTab === key, - isEnabled: true, onClick: () => setActiveTab(key as TabId), }))} tabClassName="font-medium" diff --git a/apps/dashboard/src/app/login/onboarding/LoginOrSignup/LoginOrSignup.tsx b/apps/dashboard/src/app/login/onboarding/LoginOrSignup/LoginOrSignup.tsx index 56f377af1f6..26387bbe28d 100644 --- a/apps/dashboard/src/app/login/onboarding/LoginOrSignup/LoginOrSignup.tsx +++ b/apps/dashboard/src/app/login/onboarding/LoginOrSignup/LoginOrSignup.tsx @@ -89,13 +89,11 @@ export function LoginOrSignup(props: { name: "Create account", onClick: () => setTab("signup"), isActive: tab === "signup", - isEnabled: true, }, { name: "I already have an account", onClick: () => setTab("login"), isActive: tab === "login", - isEnabled: true, }, ]} /> diff --git a/apps/dashboard/src/app/login/onboarding/team-onboarding/InviteTeamMembers.tsx b/apps/dashboard/src/app/login/onboarding/team-onboarding/InviteTeamMembers.tsx index fdde54c80a9..c857259ff98 100644 --- a/apps/dashboard/src/app/login/onboarding/team-onboarding/InviteTeamMembers.tsx +++ b/apps/dashboard/src/app/login/onboarding/team-onboarding/InviteTeamMembers.tsx @@ -227,13 +227,11 @@ function InviteModalContent(props: { name: "Starter", onClick: () => setPlanToShow("starter"), isActive: planToShow === "starter", - isEnabled: true, }, { name: "Growth", onClick: () => setPlanToShow("growth"), isActive: planToShow === "growth", - isEnabled: true, }, ]} /> diff --git a/apps/dashboard/src/app/login/onboarding/team-onboarding/team-onboarding.tsx b/apps/dashboard/src/app/login/onboarding/team-onboarding/team-onboarding.tsx index 80881e0367c..263f10e88b2 100644 --- a/apps/dashboard/src/app/login/onboarding/team-onboarding/team-onboarding.tsx +++ b/apps/dashboard/src/app/login/onboarding/team-onboarding/team-onboarding.tsx @@ -1,13 +1,13 @@ "use client"; import { getBillingCheckoutUrl } from "@/actions/billing"; +import { apiServerProxy } from "@/actions/proxies"; import { sendTeamInvites } from "@/actions/sendTeamInvite"; import type { Team } from "@/api/team"; import { useDashboardRouter } from "@/lib/DashboardRouter"; import { toast } from "sonner"; import type { ThirdwebClient } from "thirdweb"; import { upload } from "thirdweb/storage"; -import { apiServerProxy } from "../../../../@/actions/proxies"; import { useTrack } from "../../../../hooks/analytics/useTrack"; import { updateTeam } from "../../../team/[team_slug]/(team)/~/settings/general/updateTeam"; import { InviteTeamMembersUI } from "./InviteTeamMembers"; diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/analytics/page.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/analytics/page.tsx index ec277af0edc..fa562b36c81 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/analytics/page.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/analytics/page.tsx @@ -63,7 +63,12 @@ export default async function TeamOverviewPage(props: { return (
- +
}> diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/configuration/components/engine-wallet-config.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/configuration/components/engine-wallet-config.tsx index dcbea8b6a19..8bb3431cf02 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/configuration/components/engine-wallet-config.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/configuration/components/engine-wallet-config.tsx @@ -86,7 +86,6 @@ export const EngineWalletConfig: React.FC = ({ key, name, isActive: activeTab === key, - isEnabled: true, onClick: () => setActiveTab(key), icon: (key === "aws-kms" && !isAwsKmsConfigured) || diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/settings/members/TeamMembersSettingsPage.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/settings/members/TeamMembersSettingsPage.tsx index f04f8444f66..97dcd6659fc 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/settings/members/TeamMembersSettingsPage.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/settings/members/TeamMembersSettingsPage.tsx @@ -62,13 +62,11 @@ export function TeamMembersSettingsPage(props: { isActive: manageTab === "members", name: "Team Members", onClick: () => setManageTab("members"), - isEnabled: true, }, { isActive: manageTab === "invites", name: "Pending Invites", onClick: () => setManageTab("invites"), - isEnabled: true, }, ]} /> diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/ProjectFTUX/IntegrateAPIKeyCodeTabs.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/ProjectFTUX/IntegrateAPIKeyCodeTabs.tsx new file mode 100644 index 00000000000..6686ce5e380 --- /dev/null +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/ProjectFTUX/IntegrateAPIKeyCodeTabs.tsx @@ -0,0 +1,36 @@ +"use client"; + +import { TabButtons } from "@/components/ui/tabs"; +import { useState } from "react"; + +type TabKey = "ts" | "react" | "react-native" | "dotnet" | "unity" | "unreal"; + +const tabNames: Record = { + ts: "TypeScript", + react: "React", + "react-native": "React Native", + dotnet: ".NET", + unity: "Unity", + unreal: "Unreal Engine", +}; + +export function IntegrateAPIKeyCodeTabs(props: { + tabs: Record; +}) { + const [tab, setTab] = useState("ts"); + + return ( +
+ ({ + name, + onClick: () => setTab(key as TabKey), + isActive: tab === key, + }))} + /> +
+ {props.tabs[tab]} +
+ ); +} diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/ProjectFTUX/ProjectFTUX.stories.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/ProjectFTUX/ProjectFTUX.stories.tsx new file mode 100644 index 00000000000..dcba5ada94f --- /dev/null +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/ProjectFTUX/ProjectFTUX.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { projectStub } from "../../../../../../stories/stubs"; +import { ProjectFTUX } from "./ProjectFTUX"; + +const meta = { + title: "Project/ProjectFTUX", + component: ProjectFTUX, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + project: { + ...projectStub("foo", "bar"), + secretKeys: [ + { + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + hash: "1234567890", + masked: "1234567890", + }, + ], + }, + teamSlug: "bar", + }, +}; diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/ProjectFTUX/ProjectFTUX.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/ProjectFTUX/ProjectFTUX.tsx new file mode 100644 index 00000000000..483487ff84c --- /dev/null +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/ProjectFTUX/ProjectFTUX.tsx @@ -0,0 +1,517 @@ +import type { Project } from "@/api/projects"; +import { CopyTextButton } from "@/components/ui/CopyTextButton"; +import { UnderlineLink } from "@/components/ui/UnderlineLink"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { CodeServer } from "@/components/ui/code/code.server"; +import { TrackedLinkTW } from "@/components/ui/tracked-link"; +import { + ChevronRightIcon, + CircleAlertIcon, + ExternalLinkIcon, +} from "lucide-react"; +import { ContractIcon } from "../../../../../(dashboard)/(chain)/components/server/icons/ContractIcon"; +import { EngineIcon } from "../../../../../(dashboard)/(chain)/components/server/icons/EngineIcon"; +import { InsightIcon } from "../../../../../(dashboard)/(chain)/components/server/icons/InsightIcon"; +import { DotNetIcon } from "../../../../../../components/icons/brand-icons/DotNetIcon"; +import { GithubIcon } from "../../../../../../components/icons/brand-icons/GithubIcon"; +import { ReactIcon } from "../../../../../../components/icons/brand-icons/ReactIcon"; +import { TypeScriptIcon } from "../../../../../../components/icons/brand-icons/TypeScriptIcon"; +import { UnityIcon } from "../../../../../../components/icons/brand-icons/UnityIcon"; +import { UnrealIcon } from "../../../../../../components/icons/brand-icons/UnrealIcon"; +import { NebulaIcon } from "../../../../../nebula-app/(app)/icons/NebulaIcon"; +import { IntegrateAPIKeyCodeTabs } from "./IntegrateAPIKeyCodeTabs"; +import { SecretKeySection } from "./SecretKeySection"; + +export function ProjectFTUX(props: { project: Project; teamSlug: string }) { + return ( +
+ + + + +
+ ); +} + +// Integrate API key section ------------------------------------------------------------ + +function IntegrateAPIKeySection({ + project, + teamSlug, +}: { + project: Project; + teamSlug: string; +}) { + const secretKeyMasked = project.secretKeys[0]?.masked; + const clientId = project.publishableKey; + + return ( +
+

+ Integrate API key +

+ +
+
+
+

Client ID

+

+ Identifies your application. +

+ + +
+ + {secretKeyMasked && ( + + )} +
+ +
+ +
+
+ ); +} + +function IntegrationCodeExamples(props: { + project: Project; + teamSlug: string; +}) { + return ( + + ), + react: ( + + ), + "react-native": ( + + ), + unity: ( + + + + Configure Client ID in Thirdweb Manager prefab + + + Configure "Client ID" and "Bundle ID" in{" "} + + Thirdweb Manager prefab + + + Make sure to configure your app's bundle ID in "Allowed Bundle + IDs" in{" "} + + Project settings + + + + + ), + dotnet: ( +
+ + + + + Configure your app's bundle ID in "Allowed Bundle IDs" in + Project + + + Go to{" "} + + Project settings + {" "} + and add your app's bundle ID to the "Allowed Bundle IDs" list. + + +
+ ), + unreal: ( + + + + Configure Client ID in Thirdweb Unreal Plugin{" "} + + + Configure "Client ID" and "Bundle ID" in{" "} + + thirdweb plugin settings + + + Make sure to configure your app's bundle ID in "Allowed Bundle + IDs" in{" "} + + Project settings + + + + + ), + }} + /> + ); +} + +const typescriptCodeExample = (project: Project) => `\ +import { createThirdwebClient } from "thirdweb"; + +const client = createThirdwebClient({ + // use clientId for client side usage + clientId: "${project.publishableKey}", + // use secretKey for server side usage + secretKey: "${project.secretKeys[0]?.masked}", // replace this with full secret key +});`; + +const reactCodeExample = (project: Project) => `\ +import { createThirdwebClient } from "thirdweb"; + +const client = createThirdwebClient({ + clientId: "${project.publishableKey}", +});`; + +const dotNotCodeExample = (project: Project) => `\ +using Thirdweb; + +// For web applications +var client = ThirdwebClient.Create(clientId: "${project.publishableKey}"); + +// For native applications - Replace "yourBundleId" with your app's bundle ID +var client = ThirdwebClient.Create(clientId: "${project.publishableKey}", bundleId: "yourBundleId"); + +// For backend applications (Note: below shown secret key is not the full secret key) +var client = ThirdwebClient.Create(secretKey: "${project.secretKeys[0]?.masked}");`; + +// products section ------------------------------------------------------------ + +function ProductsSection(props: { + teamSlug: string; + projectSlug: string; +}) { + const products: Array<{ + title: string; + description: string; + href: string; + icon: React.FC<{ className?: string }>; + trackingLabel: string; + }> = [ + { + title: "Engine", + description: + "Scale your application with a backend server to read, write, and deploy contracts at production-grade.", + href: `/team/${props.teamSlug}/~/engine`, + icon: EngineIcon, + trackingLabel: "engine", + }, + { + title: "Contracts", + description: + "Deploy your own contracts or leverage existing solutions for onchain implementation", + href: `/team/${props.teamSlug}/${props.projectSlug}/contracts`, + icon: ContractIcon, + trackingLabel: "contracts", + }, + { + title: "Insight", + description: + "Add indexing capabilities to retrieve real-time onchain data", + href: `/team/${props.teamSlug}/${props.projectSlug}/insight`, + icon: InsightIcon, + trackingLabel: "insight", + }, + { + title: "Nebula", + description: + "Integrate a blockchain AI model to improve your users insight into your application and the blockchain", + href: `/team/${props.teamSlug}/~/nebula`, + icon: NebulaIcon, + trackingLabel: "nebula", + }, + ]; + + return ( +
+

+ Complete your full-stack application +

+

+ Tools to build frontend, backend, and onchain with built-in + infrastructure and analytics. +

+ +
+ + {/* Feature Cards */} +
+ {products.map((product) => ( + + ))} +
+
+ ); +} + +function ProductCard(props: { + title: string; + description: string; + href: string; + icon: React.FC<{ className?: string }>; + trackingLabel: string; +}) { + return ( +
+
+ +
+

+ + {props.title} + +

+

{props.description}

+
+ ); +} + +// sdk section ------------------------------------------------------------ + +type SDKCardProps = { + name: string; + href: string; + icon: React.FC<{ className?: string }>; + trackingLabel: string; +}; + +const sdks: SDKCardProps[] = [ + { + name: "TypeScript", + href: "https://portal.thirdweb.com/sdk/typescript", + icon: TypeScriptIcon, + trackingLabel: "typescript", + }, + { + name: "React", + href: "https://portal.thirdweb.com/react/v5", + icon: ReactIcon, + trackingLabel: "react", + }, + { + name: "React Native", + href: "https://portal.thirdweb.com/react-native/v5", + icon: ReactIcon, + trackingLabel: "react_native", + }, + { + name: "Unity", + href: "https://portal.thirdweb.com/unity/v5", + icon: UnityIcon, + trackingLabel: "unity", + }, + { + name: "Unreal Engine", + href: "https://portal.thirdweb.com/unreal-engine", + icon: UnrealIcon, + trackingLabel: "unreal", + }, + { + name: ".NET", + href: "https://portal.thirdweb.com/dotnet", + icon: DotNetIcon, + trackingLabel: "dotnet", + }, +]; + +function SDKSection() { + return ( +
+

Client SDKs

+
+ {sdks.map((sdk) => ( + + ))} +
+
+ ); +} + +function SDKCard(props: SDKCardProps) { + return ( +
+
+ +
+
+

+ + {props.name} + +

+

+ View Docs + +

+
+
+ ); +} + +// starter kits section ------------------------------------------------------------ + +type StartedKitCardProps = { + name: string; + href: string; + trackingLabel: string; +}; + +const startedKits: StartedKitCardProps[] = [ + { + name: "Next Starter", + href: "https://github.com/thirdweb-example/next-starter", + trackingLabel: "next_starter", + }, + { + name: "Vite Starter", + href: "https://github.com/thirdweb-example/vite-starter", + trackingLabel: "vite_starter", + }, + { + name: "Expo Starter", + href: "https://github.com/thirdweb-example/expo-starter", + trackingLabel: "expo_starter", + }, + { + name: "Node Starter", + href: "https://github.com/thirdweb-example/node-starter", + trackingLabel: "node_starter", + }, +]; + +function StarterKitsSection() { + return ( +
+
+

Starter Kits

+ + View all + +
+ +
+ {startedKits.map((kit) => ( + + ))} +
+
+ ); +} + +function StarterKitCard(props: StartedKitCardProps) { + return ( +
+
+ +
+ +
+ + {props.name} + +

+ View Repo + +

+
+
+ ); +} diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/ProjectFTUX/SecretKeySection.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/ProjectFTUX/SecretKeySection.tsx new file mode 100644 index 00000000000..030811e0c33 --- /dev/null +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/ProjectFTUX/SecretKeySection.tsx @@ -0,0 +1,38 @@ +"use client"; + +import { rotateSecretKeyClient } from "@3rdweb-sdk/react/hooks/useApi"; +import { useState } from "react"; +import { RotateSecretKeyButton } from "../../settings/ProjectGeneralSettingsPage"; + +export function SecretKeySection(props: { + secretKeyMasked: string; + projectId: string; +}) { + const [secretKeyMasked, setSecretKeyMasked] = useState(props.secretKeyMasked); + + return ( +
+

Secret Key

+

+ Identifies and authenticates your application from a backend.
{" "} + This is not the full secret key, Refer to your saved secret key at the + time of creation for the full secret key. +

+ +
+
+ {secretKeyMasked} +
+ + { + return rotateSecretKeyClient(props.projectId); + }} + onSuccess={(data) => { + setSecretKeyMasked(data.data.secretMasked); + }} + /> +
+
+ ); +} diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/nebula/components/analytics/nebula-analytics-ui.stories.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/nebula/components/analytics/nebula-analytics-ui.stories.tsx index ab791a3cab4..10e3815c89e 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/nebula/components/analytics/nebula-analytics-ui.stories.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/nebula/components/analytics/nebula-analytics-ui.stories.tsx @@ -43,25 +43,21 @@ function Story() { name: "60 Days", onClick: () => setTab("60-day"), isActive: tab === "60-day", - isEnabled: true, }, { name: "30 Days", onClick: () => setTab("30-day"), isActive: tab === "30-day", - isEnabled: true, }, { name: "7 Days", onClick: () => setTab("7-day"), isActive: tab === "7-day", - isEnabled: true, }, { name: "Pending", onClick: () => setTab("pending"), isActive: tab === "pending", - isEnabled: true, }, ]} /> diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/page.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/page.tsx index d0ed85f435a..5de6e1a3ea4 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/page.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/page.tsx @@ -31,8 +31,8 @@ import { import { type WalletId, getWalletInfo } from "thirdweb/wallets"; import { AnalyticsHeader } from "../../components/Analytics/AnalyticsHeader"; import { CombinedBarChartCard } from "../../components/Analytics/CombinedBarChartCard"; -import { EmptyState } from "../../components/Analytics/EmptyState"; import { PieChartCard } from "../../components/Analytics/PieChartCard"; +import { ProjectFTUX } from "./components/ProjectFTUX/ProjectFTUX"; import { RpcMethodBarChartCard } from "./components/RpcMethodBarChartCard"; import { TransactionsCharts } from "./components/Transactions"; @@ -85,11 +85,13 @@ export default async function ProjectOverviewPage(props: PageProps) { title={project.name} interval={interval} range={range} + showRangeSelector={isActive} />
+ {!isActive ? ( -
- +
+
) : (
diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/settings/ProjectGeneralSettingsPage.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/settings/ProjectGeneralSettingsPage.tsx index bfefbe00090..542e3012692 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/settings/ProjectGeneralSettingsPage.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/settings/ProjectGeneralSettingsPage.tsx @@ -984,7 +984,7 @@ function DeleteProject(props: { ); } -function RotateSecretKeyButton(props: { +export function RotateSecretKeyButton(props: { rotateSecretKey: RotateSecretKey; onSuccess: (data: RotateSecretKeyAPIReturnType) => void; }) { diff --git a/apps/dashboard/src/app/team/components/Analytics/AnalyticsHeader.stories.tsx b/apps/dashboard/src/app/team/components/Analytics/AnalyticsHeader.stories.tsx index a7043b6df38..3cc2fbab3e5 100644 --- a/apps/dashboard/src/app/team/components/Analytics/AnalyticsHeader.stories.tsx +++ b/apps/dashboard/src/app/team/components/Analytics/AnalyticsHeader.stories.tsx @@ -39,6 +39,7 @@ function Component() { title="Project Overview" interval="day" range={getLastNDaysRange("last-120")} + showRangeSelector={true} />
diff --git a/apps/dashboard/src/app/team/components/Analytics/AnalyticsHeader.tsx b/apps/dashboard/src/app/team/components/Analytics/AnalyticsHeader.tsx index 74beef5b625..d70cce057e7 100644 --- a/apps/dashboard/src/app/team/components/Analytics/AnalyticsHeader.tsx +++ b/apps/dashboard/src/app/team/components/Analytics/AnalyticsHeader.tsx @@ -5,8 +5,9 @@ export function AnalyticsHeader(props: { title: string; interval: "day" | "week"; range: Range; + showRangeSelector: boolean; }) { - const { title, interval, range } = props; + const { title, interval, range, showRangeSelector } = props; return (
@@ -15,7 +16,7 @@ export function AnalyticsHeader(props: { {title}
- + {showRangeSelector && }
); } diff --git a/apps/dashboard/src/app/team/components/NotificationButton/NotificationButton.tsx b/apps/dashboard/src/app/team/components/NotificationButton/NotificationButton.tsx index 9cd17a70ecd..046a7ef5313 100644 --- a/apps/dashboard/src/app/team/components/NotificationButton/NotificationButton.tsx +++ b/apps/dashboard/src/app/team/components/NotificationButton/NotificationButton.tsx @@ -153,7 +153,6 @@ export function NotificationButtonInner(props: { /> ), onClick: () => setTab("inbox"), - isEnabled: true, }, { isActive: tab === "changelogs", @@ -164,7 +163,6 @@ export function NotificationButtonInner(props: { /> ), onClick: () => setTab("changelogs"), - isEnabled: true, }, ]} />