From b2acba4c2c6f53f9ed0025983ea0eebb8bace30e Mon Sep 17 00:00:00 2001 From: isra el Date: Sun, 19 Jul 2026 02:20:39 +0300 Subject: [PATCH] fix: tidy the community page and close mobile layout gaps community-links was the only file in the app still wrapping a Button in a Link, four times, producing an anchor around a button: invalid markup and a nested interactive control that assistive tech announces twice. Everywhere else already uses Button asChild. Two whole Card blocks sat commented out, with an icon imported solely for that dead code. community/page.tsx was the only dashboard section that never got the mobile pass, keeping p-6 with no p-4 step and an unconditional text-3xl. It was also the only section missing from the 375px overflow guard, which is presumably how it was missed. Extracting the shared PageHeader, which the messaging, webhooks and account layouts all repeated by hand, fixes that outlier by construction. Both billing limit grids and the promo modal were locked to two columns at every width, so the meter captions had no room on a phone. window.open kept a live opener handle back to the app in four places. Browsers imply noopener for anchor targets but not for window.open. The share dialog grid moves to 3 columns then 7. Worth stating plainly: this is not an overflow fix. I expected 7 icons at grid-cols-4 to overflow at 375px and the extended guard proved they do not. It was only an awkward 4 + 3 split. The overflow guard now covers 12 routes instead of 6 and opens a dialog, since the densest layouts in the app only exist inside modals. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../(components)/black-friday-modal.tsx | 2 +- .../(components)/community-links.tsx | 134 +++++++----------- .../(components)/get-started/step-actions.tsx | 2 +- .../(components)/subscription-info.tsx | 4 +- web/app/(app)/dashboard/account/layout.tsx | 17 +-- web/app/(app)/dashboard/community/page.tsx | 23 ++- web/app/(app)/dashboard/messaging/layout.tsx | 17 +-- web/app/(app)/dashboard/page.tsx | 6 +- web/app/(app)/dashboard/webhooks/layout.tsx | 17 +-- .../shared/join-community-modal.tsx | 2 +- web/components/shared/page-header.tsx | 40 ++++++ web/e2e/mobile-overflow.spec.ts | 28 ++++ 12 files changed, 162 insertions(+), 130 deletions(-) create mode 100644 web/components/shared/page-header.tsx diff --git a/web/app/(app)/dashboard/(components)/black-friday-modal.tsx b/web/app/(app)/dashboard/(components)/black-friday-modal.tsx index 4a41dc2..7668f61 100644 --- a/web/app/(app)/dashboard/(components)/black-friday-modal.tsx +++ b/web/app/(app)/dashboard/(components)/black-friday-modal.tsx @@ -87,7 +87,7 @@ export default function BlackFridayModal() {
{/* Benefits List */} -
+
{[ "Increased SMS limits", "No daily limits", diff --git a/web/app/(app)/dashboard/(components)/community-links.tsx b/web/app/(app)/dashboard/(components)/community-links.tsx index a549dad..e6b92a4 100644 --- a/web/app/(app)/dashboard/(components)/community-links.tsx +++ b/web/app/(app)/dashboard/(components)/community-links.tsx @@ -3,7 +3,6 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Github, - Heart, MessageSquare, Linkedin, Twitter, @@ -18,6 +17,7 @@ import { toast } from '@/hooks/use-toast' import { DialogHeader, DialogTitle, + DialogDescription, Dialog, DialogContent, } from '@/components/ui/dialog' @@ -77,41 +77,7 @@ export default function CommunityLinks() { return ( <> -
- {/* - - One-time Donation - - -

- Support us with a one-time donation of your desired amount. -

- - - -
-
*/} - - {/* - - Support on Patreon - - -

- Support the development by becoming a patron. -

- - - -
-
*/} - +
GitHub @@ -120,12 +86,12 @@ export default function CommunityLinks() {

Check out our source code and contribute to the project.

- - - + +
@@ -137,12 +103,12 @@ export default function CommunityLinks() {

Join our community for support and updates.

- - - + + @@ -154,12 +120,12 @@ export default function CommunityLinks() {

Follow us on X for the latest updates and announcements.

- - - + + @@ -171,16 +137,12 @@ export default function CommunityLinks() {

Connect with us on LinkedIn for updates and news.

- - - + + @@ -205,36 +167,50 @@ export default function CommunityLinks() { - + Share textbee.dev with Others -

+ {/* A bare

here left the dialog with no aria-describedby. */} + Help us grow by sharing textbee.dev with your friends and - colleagues! -

+ colleagues. +

Choose your platform

-
- {socials.map(({ icon, name, url }) => ( - - ))} + {/* Not an overflow fix: 7 platforms at grid-cols-4 did fit at + 375px, verified against the overflow guard. It just read + badly, a 4 + 3 split with a stranded last row. Three columns + on the smallest screens, then one clean row of seven. */} +
+ {socials.map(({ icon, name, url }) => ( + + ))}
@@ -259,7 +235,7 @@ export default function CommunityLinks() { {copiedUrl === currentUrl ? 'Copied!' : 'Copy Link'}
-
+
@@ -398,7 +398,7 @@ export default function SubscriptionInfo() {

)}
-
+
{limitTiles.map((tile) => ( ))} diff --git a/web/app/(app)/dashboard/account/layout.tsx b/web/app/(app)/dashboard/account/layout.tsx index a0ca9af..7769a1f 100644 --- a/web/app/(app)/dashboard/account/layout.tsx +++ b/web/app/(app)/dashboard/account/layout.tsx @@ -1,6 +1,7 @@ import type { PropsWithChildren } from 'react' import { UserIcon } from 'lucide-react' import RouteTabs from '@/components/shared/route-tabs' +import PageHeader from '@/components/shared/page-header' // Account is one settings experience: sections are route-based tabs (same // interaction grammar as messaging/webhooks), Billing first since the @@ -8,17 +9,11 @@ import RouteTabs from '@/components/shared/route-tabs' export default function AccountLayout({ children }: PropsWithChildren) { return (
-
-
- -

- Account -

-
-

- Manage your subscription, profile and security -

-
+ -
-
- -

Community

-
-

Connect with other users and find support

-
- -
- -
+ // p-4 on mobile, matching every other dashboard section. This page was the + // only one still starting at p-6, and the only one absent from the 375px + // overflow guard, which is presumably how it was missed. +
+ +
) } diff --git a/web/app/(app)/dashboard/messaging/layout.tsx b/web/app/(app)/dashboard/messaging/layout.tsx index d5a9275..28e999d 100644 --- a/web/app/(app)/dashboard/messaging/layout.tsx +++ b/web/app/(app)/dashboard/messaging/layout.tsx @@ -1,6 +1,7 @@ import type { PropsWithChildren } from 'react' import { MessageSquareTextIcon } from 'lucide-react' import RouteTabs from '@/components/shared/route-tabs' +import PageHeader from '@/components/shared/page-header' // Messaging section shell: shared header + route-based tabs, so the active // tab survives refresh and every view has a shareable URL. @@ -13,17 +14,11 @@ export default function MessagingLayout({ children }: PropsWithChildren) { return (
-
-
- -

- Messaging -

-
-

- Send messages and view your SMS history -

-
+ window.open('https://textbee.dev/quickstart', '_blank')} + onClick={() => window.open( + 'https://textbee.dev/quickstart', + '_blank', + 'noopener,noreferrer' + )} > Quick Start diff --git a/web/app/(app)/dashboard/webhooks/layout.tsx b/web/app/(app)/dashboard/webhooks/layout.tsx index 6f32eeb..42b373f 100644 --- a/web/app/(app)/dashboard/webhooks/layout.tsx +++ b/web/app/(app)/dashboard/webhooks/layout.tsx @@ -1,23 +1,18 @@ import type { PropsWithChildren } from 'react' import { Webhook } from 'lucide-react' import RouteTabs from '@/components/shared/route-tabs' +import PageHeader from '@/components/shared/page-header' // Webhooks section shell: subscriptions management and delivery history are // route-based tabs, so the active view survives refresh. export default function WebhooksLayout({ children }: PropsWithChildren) { return (
-
-
- -

- Webhooks -

-
-

- Get notified at your endpoints when SMS events happen -

-
+ {