Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ function Story() {
<div className="container flex max-w-[1000px] flex-col gap-8 py-10">
<Variant label="10 Pages" totalPages={10} />
<Variant label="100 Pages" totalPages={100} />
<Variant label="3 Pages" totalPages={2} />
<Variant label="2 Pages" totalPages={2} />
<Variant label="3 Pages" totalPages={3} />
<Variant label="6 Pages" totalPages={6} />
<Variant label="1 Page - nothing rendered" totalPages={1} />
</div>
Expand Down
21 changes: 16 additions & 5 deletions apps/dashboard/src/@/components/pagination-buttons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const PaginationButtons = (props: {
<PaginationContent>
<PaginationItem>
<PaginationPrevious
className="rounded-full"
disabled={activePage === 1}
onClick={() => {
setPage(activePage - 1);
Expand All @@ -56,6 +57,7 @@ export const PaginationButtons = (props: {
</PaginationItem>
<PaginationItem>
<PaginationNext
className="rounded-full"
disabled={activePage === totalPages}
onClick={() => {
setPage(activePage + 1);
Expand All @@ -76,6 +78,7 @@ export const PaginationButtons = (props: {
{pages.map((page) => (
<PaginationItem key={page}>
<PaginationLink
className="rounded-full"
isActive={activePage === page}
onClick={() => {
setPage(page);
Expand All @@ -95,6 +98,7 @@ export const PaginationButtons = (props: {
<PaginationContent>
<PaginationItem>
<PaginationPrevious
className="rounded-full"
disabled={activePage === 1}
onClick={() => {
setPage(activePage - 1);
Expand All @@ -107,6 +111,7 @@ export const PaginationButtons = (props: {
<>
<PaginationItem>
<PaginationLink
className="rounded-full"
onClick={() => {
setPage(1);
}}
Expand All @@ -116,14 +121,15 @@ export const PaginationButtons = (props: {
</PaginationItem>

<PaginationItem>
<PaginationEllipsis className="max-sm:w-3" />
<PaginationEllipsis className="max-sm:w-3 rounded-full" />
</PaginationItem>
</>
)}

{activePage - 1 > 0 && (
<PaginationItem className="max-sm:hidden">
<PaginationLink
className="rounded-full"
onClick={() => {
setPage(activePage - 1);
}}
Expand All @@ -134,12 +140,15 @@ export const PaginationButtons = (props: {
)}

<PaginationItem>
<PaginationLink isActive>{activePage}</PaginationLink>
<PaginationLink className="rounded-full" isActive>
{activePage}
</PaginationLink>
</PaginationItem>

{activePage + 1 <= totalPages && (
<PaginationItem className="max-sm:hidden">
<PaginationLink
className="rounded-full"
onClick={() => {
setPage(activePage + 1);
}}
Expand All @@ -153,11 +162,12 @@ export const PaginationButtons = (props: {
{activePage + 3 <= totalPages && (
<>
<PaginationItem>
<PaginationEllipsis className="max-sm:w-3" />
<PaginationEllipsis className="max-sm:w-3 rounded-full" />
</PaginationItem>

<PaginationItem>
<PaginationLink
className="rounded-full"
onClick={() => {
setPage(totalPages);
}}
Expand All @@ -170,6 +180,7 @@ export const PaginationButtons = (props: {

<PaginationItem>
<PaginationNext
className="rounded-full"
disabled={activePage === totalPages}
onClick={() => {
setPage(activePage + 1);
Expand All @@ -180,7 +191,7 @@ export const PaginationButtons = (props: {
<div className="relative flex items-center">
<Input
className={cn(
"w-[60px] bg-transparent [appearance:textfield] max-sm:placeholder:text-sm lg:w-[100px] lg:pr-8 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
"w-[60px] bg-transparent [appearance:textfield] max-sm:placeholder:text-sm lg:w-[100px] lg:pr-8 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none rounded-full",
inputHasError && "text-red-500",
)}
onChange={(e) => {
Expand All @@ -197,7 +208,7 @@ export const PaginationButtons = (props: {
value={pageNumberInput}
/>
<Button
className="absolute right-1 h-auto w-auto p-2 max-sm:hidden"
className="absolute right-1 h-auto w-auto rounded-full p-2 max-sm:hidden"
onClick={handlePageInputSubmit}
variant="ghost"
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,55 +1,92 @@
import { formatDistance } from "date-fns";
import { ArrowRightIcon } from "lucide-react";
import { ArrowRightIcon, FileTextIcon } from "lucide-react";
import { unstable_cache } from "next/cache";
import Link from "next/link";
import { Img } from "@/components/blocks/Img";
import { Button } from "@/components/ui/button";

type ChangelogItem = {
published_at: string;
title: string;
url: string;
feature_image: string;
};

export async function Changelog() {
const changelog = await getChangelog();

return (
<div className="relative flex flex-col gap-6 border-border border-l py-2">
{changelog.map((item) => (
<div className="flex flex-row gap-2" key={item.title}>
<div className="-translate-x-1/2 size-2.5 shrink-0 translate-y-1/2 rounded-full bg-border" />
<div className="relative flex grow flex-col">
<div className="mb-4 flex items-center justify-between gap-4">
<div>
<h2 className="mb-1 font-semibold text-2xl tracking-tight">
Changelog
</h2>
<p className="text-muted-foreground text-sm">
View the latest updates to thirdweb products and services
</p>
</div>

<Button
asChild
className="gap-2 rounded-full bg-card"
variant="outline"
>
<Link
href="https://blog.thirdweb.com/changelog?utm_source=thirdweb&utm_campaign=changelog"
rel="noopener noreferrer"
target="_blank"
>
View All <ArrowRightIcon className="size-4" />
</Link>
</Button>
</div>

<div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
{changelog.map((item) => (
<div
className="relative overflow-hidden rounded-xl border bg-card hover:border-active-border"
key={item.title}
>
<Img
alt={item.title}
className="aspect-video w-full object-cover"
fallback={
<div className="flex items-center justify-center bg-gradient-to-b from-card to-accent">
<div className="rounded-full border p-3">
<FileTextIcon className="size-5 text-muted-foreground" />
</div>
</div>
}
src={item.feature_image}
/>

<div className="flex flex-col">
<Link
className="line-clamp-2 text-foreground text-sm hover:underline"
href={`${item.url}?utm_source=thirdweb&utm_campaign=changelog`}
target="_blank"
>
{item.title}
</Link>
<div className="mt-1 text-muted-foreground text-xs">
{formatDistance(new Date(item.published_at), Date.now(), {
addSuffix: true,
})}
<div className="border-t px-3 py-4">
<Link
className="mb-2 line-clamp-2 font-medium text-base text-foreground before:absolute before:inset-0"
href={`${item.url}?utm_source=thirdweb&utm_campaign=changelog`}
target="_blank"
>
{item.title}
</Link>

<div className="text-muted-foreground text-sm">
{formatDistance(new Date(item.published_at), Date.now(), {
addSuffix: true,
})}
</div>
</div>
</div>
</div>
))}
<Link
className="flex items-center gap-2 pl-5 text-foreground text-sm hover:underline"
href="https://blog.thirdweb.com/changelog?utm_source=thirdweb&utm_campaign=changelog"
rel="noopener noreferrer"
target="_blank"
>
View More <ArrowRightIcon className="size-4" />
</Link>
))}
</div>
</div>
);
}

const getChangelog = unstable_cache(
async () => {
const res = await fetch(
"https://thirdweb.ghost.io/ghost/api/content/posts/?key=49c62b5137df1c17ab6b9e46e3&fields=title,url,published_at&filter=tag:changelog&visibility:public&limit=10",
"https://thirdweb.ghost.io/ghost/api/content/posts/?key=49c62b5137df1c17ab6b9e46e3&fields=title,url,published_at,feature_image&filter=tag:changelog&visibility:public&limit=12",
);
if (!res.ok) {
return [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Button } from "@/components/ui/button";

export function InviteTeamMembersButton(props: { teamSlug: string }) {
return (
<Button asChild className="gap-2" variant="outline">
<Button asChild className="gap-2 rounded-full bg-card" variant="outline">
<Link href={`/team/${props.teamSlug}/~/settings/members`}>
<UserPlusIcon className="size-4" />
<span>Invite Team Members</span>
Expand Down
45 changes: 16 additions & 29 deletions apps/dashboard/src/app/(app)/team/[team_slug]/(team)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default async function Page(props: {
return (
<div className="flex grow flex-col">
<div className="border-border border-b">
<div className="container flex flex-col items-start gap-3 py-10 md:flex-row md:items-center">
<div className="container flex max-w-6xl flex-col items-start gap-3 py-10 md:flex-row md:items-center">
<div className="flex-1">
<h1 className="font-semibold text-3xl tracking-tight">
Team Overview
Expand All @@ -53,37 +53,24 @@ export default async function Page(props: {
</div>
</div>

<div className="container flex grow flex-col gap-4 lg:flex-row">
{/* left */}
<div className="flex grow flex-col gap-6 pt-8 lg:pb-20">
{team.billingPlan === "free" ? (
<FreePlanUpsellBannerUI
highlightPlan="growth"
teamSlug={team.slug}
/>
) : (
<DismissibleAlert
description="Engines, contracts, project settings, and more are now managed within projects. Open or create a project to access them."
localStorageId={`${team.id}-engines-alert`}
title="Looking for Engines?"
/>
)}
<div className="container flex max-w-6xl flex-col gap-10 py-6 pb-20">
<TeamProjectsPage
client={client}
projects={projectsWithTotalWallets}
team={team}
/>

<TeamProjectsPage
client={client}
projects={projectsWithTotalWallets}
team={team}
{team.billingPlan === "free" ? (
<FreePlanUpsellBannerUI highlightPlan="growth" teamSlug={team.slug} />
) : (
<DismissibleAlert
description="Engines, contracts, project settings, and more are now managed within projects. Open or create a project to access them."
localStorageId={`${team.id}-engines-alert`}
title="Looking for Engines?"
/>
</div>

{/* right */}
<div className="w-full px-4 py-8 lg:w-[300px]">
<h2 className="mb-3 font-semibold text-2xl tracking-tight">
Changelog
</h2>
)}

<Changelog />
</div>
<Changelog />
</div>
</div>
);
Expand Down
Loading
Loading