Skip to content

Commit

Permalink
feat: add super and such to marketing
Browse files Browse the repository at this point in the history
  • Loading branch information
darraghoriordan committed Mar 18, 2023
1 parent 3967416 commit 064118c
Show file tree
Hide file tree
Showing 55 changed files with 1,856 additions and 272 deletions.
18 changes: 6 additions & 12 deletions apps/backend/open-api/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -1582,8 +1582,7 @@
"userId",
"organisationId",
"createdDate",
"updateDate",
"deletedDate"
"updateDate"
]
},
"UserApiKey": {
Expand Down Expand Up @@ -1624,8 +1623,7 @@
"description",
"userId",
"createdDate",
"updateDate",
"deletedDate"
"updateDate"
]
},
"UserDto": {
Expand Down Expand Up @@ -1702,8 +1700,7 @@
"memberships",
"apiKeys",
"createdDate",
"updateDate",
"deletedDate"
"updateDate"
]
},
"UpdateUserDto": {
Expand Down Expand Up @@ -1778,8 +1775,7 @@
"uuid",
"name",
"createdDate",
"updateDate",
"deletedDate"
"updateDate"
]
},
"User": {
Expand Down Expand Up @@ -1850,8 +1846,7 @@
"emailVerified",
"blocked",
"createdDate",
"updateDate",
"deletedDate"
"updateDate"
]
},
"UpdateOrganisationDto": {
Expand Down Expand Up @@ -2080,8 +2075,7 @@
"validUntil",
"organisationId",
"createdDate",
"updatedDate",
"deletedDate"
"updatedDate"
]
},
"SaveOrganisationSubscriptionRecordDto": {
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/src/account/NoSubscriptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function NoSubscriptions({
You have no subscriptions.
</h3>
<p className="mt-6 text-sm text-gray-200">
Get started with Miller by subscribing.
Get started by subscribing.
</p>
<div className="mt-6">
<StyledButton onClick={onClick}>
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/src/layout/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Fragment, PropsWithChildren, useState } from "react";
import { Fragment, PropsWithChildren } from "react";
import { NavLink } from "react-router-dom";
import { Popover, Transition } from "@headlessui/react";
import clsx from "clsx";
Expand Down
11 changes: 3 additions & 8 deletions apps/marketing/src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,9 @@ export const MobileNavigation = () => {
Features
</MobileNavLink>
<MobileNavLink href="/#pricing">Pricing</MobileNavLink>
<MobileNavLink href="/docs/">Features</MobileNavLink>
{user && (
<MobileNavLink
href={process.env.NEXT_PUBLIC_APP_BASE_PATH}
>
<MobileNavLink href={"/dashboard"}>
Dashboard
</MobileNavLink>
)}
Expand Down Expand Up @@ -170,11 +169,7 @@ export function Header() {
<a href="/api/auth/login">Sign In</a>
)}
{user && (
<NavLink
href={process.env.NEXT_PUBLIC_APP_BASE_PATH}
>
Dashboard
</NavLink>
<NavLink href={"/dashboard"}>Dashboard</NavLink>
)}
</div>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { colorVariants } from "@use-miller/shared-frontend-tooling";
import clsx from "clsx";
import Link from "next/link.js";
import { useRouter } from "next/router.js";
import { LeftMenuItem } from "./LeftMenuItem.js";

Expand All @@ -24,23 +25,36 @@ const isCurrentMenuItem = (path: string, item: MenuItem) => {
return item.path === path;
};

export function LeftMenu({ menuSections }: { menuSections: MenuSection[] }) {
export function LeftMenu({
menuSections,
header,
headerHref,
}: {
menuSections: MenuSection[];
header: string;
headerHref?: string;
}) {
const path = useRouter();

return (
<div className="flex">
<div className="flex flex-col flex-grow ml-4 pt-[1em]">
<div className="flex flex-col flex-grow ml-4">
<h1
className={clsx(
`mb-8 font-bold uppercase`,
colorVariants["green"].foreground
)}
>
Docs
<Link
className="hover:cursor-pointer"
href={headerHref || "#"}
>
{header}
</Link>
</h1>
{menuSections?.map((section) => (
<div key={section.name}>
<h3 className="mb-2 font-bold text-white uppercase">
<h3 className="mb-2 mt-4 font-bold text-white uppercase ">
{section.name}
</h3>
<ul className="mr-4">
Expand Down
31 changes: 31 additions & 0 deletions apps/marketing/src/components/LeftMenuWrappedContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { PropsWithChildren } from "react";
import { LeftMenu, MenuSection } from "./LeftMenu.jsx";
import { Container } from "./Container.jsx";
import Layout from "./Layout.jsx";

export const LeftMenuWrappedContent = ({
menuSections,
menuHeaderTitle,
menuHeaderHref,
children,
}: {
menuSections: MenuSection[];

menuHeaderTitle: string;
menuHeaderHref: string;
} & PropsWithChildren) => {
return (
<Layout>
<Container className="w-full min-w-full mx-auto bg-neutral-900 mb-16">
<div className="flex items-stretch">
<LeftMenu
header={menuHeaderTitle}
headerHref={menuHeaderHref}
menuSections={menuSections}
/>
{children}
</div>
</Container>
</Layout>
);
};
23 changes: 23 additions & 0 deletions apps/marketing/src/dashboard/components/DashboardDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { OrganisationSubscriptionRecord } from "@use-miller/shared-api-client";
import NoSubscriptions from "./NoSubscriptions.jsx";
import { Subscriptions } from "./Subscriptions.jsx";

export const DashboardDetails = ({
title,
subs,
}: {
title: string;
subs: OrganisationSubscriptionRecord[];
}) => {
let subsComponent = <Subscriptions subs={subs} />;
if (subs.length === 0) {
subsComponent = <NoSubscriptions />;
}

return (
<div className="ml-16">
<h1 className="text-4xl font-bold text-white">{title}</h1>
<div className="mt-16 mb-32">{subsComponent}</div>
</div>
);
};
31 changes: 31 additions & 0 deletions apps/marketing/src/dashboard/components/ManageBillingLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { StyledButton } from "@use-miller/shared-frontend-tooling";
import { ArrowTopRightOnSquareIcon } from "@heroicons/react/24/outline";
import { useGetCustomerPortalSession } from "../../hooks/useGetCustomerPortalSession.js";
const ManageBillingLink = ({
subscriptionUuid,
paymentProvider,
}: {
subscriptionUuid: string;
paymentProvider: string;
}) => {
const { mutateAsync } = useGetCustomerPortalSession();
let linkClick = async (uuid: string) => {
const url = new URL(window.location.href);

const link = await mutateAsync({
returnUrl: url.pathname,
subscriptionRecordUuid: uuid,
});
// redirect to it
window.location.href = link.sessionUrl;
};

return (
<StyledButton onClick={() => linkClick(subscriptionUuid)}>
Manage Billing {paymentProvider ? "on " + paymentProvider : ""}
<ArrowTopRightOnSquareIcon className="w-5 h-5 ml-2" />
</StyledButton>
);
};

export default ManageBillingLink;
53 changes: 53 additions & 0 deletions apps/marketing/src/dashboard/components/NoSubscriptions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { ShoppingBagIcon } from "@heroicons/react/24/outline";
import {
colorVariants,
StyledButton,
} from "@use-miller/shared-frontend-tooling";
import { useGetPaymentLink } from "../../hooks/useGetPaymentLink.js";

export default function NoSubscriptions({
organisationUuid,
}: {
organisationUuid?: string;
}) {
const { mutateAsync } = useGetPaymentLink();

const onClick = async () => {
const link = await mutateAsync({
successFrontendPath: "/dashboard",
cancelFrontendPath: "/dashboard",
lineItems: [
{
price: process.env.NEXT_PUBLIC_STRIPE_REGULAR_PRICE_ID,
quantity: 1,
},
],
mode: "subscription",
organisationId: organisationUuid,
});

window.location.href = link.stripeSessionUrl;
};
const colorVariant = "green";
return (
<div
className={`p-8 overflow-hidden rounded-md text-gray-500 bg-dark-accent hover:shadow-lg ${colorVariants[colorVariant].hoverShadow} ${colorVariants[colorVariant].hoverForeground}`}
>
<h3 className="text-lg font-medium text-white">
You have no subscriptions.
</h3>
<p className="mt-6 text-sm text-gray-200">
Get started by subscribing.
</p>
<div className="mt-6">
<StyledButton onClick={onClick}>
<ShoppingBagIcon
className="w-5 h-5 mr-2 -ml-1"
aria-hidden="true"
/>
Subscribe now
</StyledButton>
</div>
</div>
);
}
23 changes: 23 additions & 0 deletions apps/marketing/src/dashboard/components/ProfileDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { User } from "@use-miller/shared-api-client";
import { useFormattedDate } from "../../hooks/useFormattedDate.js";

export const ProfileDetails = ({ currentUser }: { currentUser: User }) => {
const formattedDate = useFormattedDate(currentUser?.createdDate);
return (
<div className="ml-16 min-w-[33%]">
<h1 className="text-3xl font-bold text-white">Profile</h1>
<p className="text-sm py-2 text-white">Manage your profile</p>
<hr className="border-green-500/30"></hr>
<div className="ml-3 mt-16 mb-32 flex flex-col space-y-8">
<div className="">
<p className="mb-1 font-bold text-white">Email</p>
<p className=" text-white">{currentUser.email}</p>
</div>
<div className="">
<p className="mb-1 font-bold text-white">Member since</p>
<p className="text-white">{formattedDate}</p>
</div>
</div>
</div>
);
};
53 changes: 53 additions & 0 deletions apps/marketing/src/dashboard/components/SingleSubscription.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { OrganisationSubscriptionRecord } from "@use-miller/shared-api-client";
import { colorVariants } from "@use-miller/shared-frontend-tooling";
import { useFormattedDate } from "../../hooks/useFormattedDate.js";
import ManageBillingLink from "./ManageBillingLink.jsx";

export const SingleSubscription = ({
subscriptionRecord,
}: {
subscriptionRecord: OrganisationSubscriptionRecord;
}) => {
const expiryDate = useFormattedDate(subscriptionRecord.validUntil);
const createdDate = useFormattedDate(subscriptionRecord.createdDate);
const colorVariant = "green";
return (
<div
className={`p-8 overflow-hidden rounded-md text-gray-500 bg-dark-accent hover:shadow-lg ${colorVariants[colorVariant].hoverShadow} ${colorVariants[colorVariant].hoverForeground}`}
>
<div className="flex flex-col items-center space-y-6">
<h3 className="text-4xl font-medium text-light-accent">
{subscriptionRecord.productDisplayName}
</h3>
<div className="flex justify-between w-3/4">
{subscriptionRecord.paymentSystemMode ===
"subscription" && (
<div className="">
<p className="mb-1 font-bold text-white">
Valid Until
</p>
<p className=" text-white">{expiryDate}</p>
</div>
)}
<div className="">
<p className="mb-1 font-bold text-white">Started</p>
<p className="text-white">{createdDate}</p>
</div>
</div>
<div className="w-3/4">
<p className="mb-1 font-bold text-white">
Last Transaction Id
</p>
<p className="text-white">
{subscriptionRecord.paymentSystemTransactionId}
</p>
</div>

<ManageBillingLink
subscriptionUuid={subscriptionRecord.uuid}
paymentProvider={subscriptionRecord.paymentSystemName}
/>
</div>
</div>
);
};
27 changes: 27 additions & 0 deletions apps/marketing/src/dashboard/components/Subscriptions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { OrganisationSubscriptionRecord } from "@use-miller/shared-api-client";
import { SingleSubscription } from "./SingleSubscription.jsx";

export const Subscriptions = ({
subs,
}: {
subs: OrganisationSubscriptionRecord[];
}) => {
return (
<div className=" border-white">
<h2 className="text-3xl font-bold text-white w-full">
Your Subscriptions
</h2>

<div className="mt-16 mb-32 flex flex-col space-y-8">
{subs.map((sub) => {
return (
<SingleSubscription
key={sub.id}
subscriptionRecord={sub}
/>
);
})}
</div>
</div>
);
};
Loading

0 comments on commit 064118c

Please sign in to comment.