Update dependencies, add copy and adjust UI

This commit updates the version of Next.js along with a series of other dependencies outlined in the pnpm-lock.yaml file. The new copy "For each {{unit}}" has been added to the billing.json file and several adjustments have been made in the UI components. In particular, a separator has been added, animations have been set to re-run on re-render for certain elements, and the PricingTable component has been added.
This commit is contained in:
giancarlo
2024-04-05 17:30:37 +08:00
parent f03c619fc7
commit 1cef5ac3db
8 changed files with 114 additions and 82 deletions

View File

@@ -1,4 +1,5 @@
import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client';
import { Separator } from '@kit/ui/separator';
import { SiteFooter } from '~/(marketing)/_components/site-footer';
import { SiteHeader } from '~/(marketing)/_components/site-header';
@@ -13,6 +14,8 @@ async function SiteLayout(props: React.PropsWithChildren) {
{props.children}
<Separator />
<SiteFooter />
</>
);

View File

@@ -3,9 +3,12 @@ import Link from 'next/link';
import { ChevronRight } from 'lucide-react';
import { PricingTable } from '@kit/billing-gateway/components';
import { Button } from '@kit/ui/button';
import { Heading } from '@kit/ui/heading';
import billingConfig from '~/config/billing.config';
import pathsConfig from '~/config/paths.config';
import { withI18n } from '~/lib/i18n/with-i18n';
function Home() {
@@ -198,7 +201,14 @@ function Home() {
</div>
</div>
<div className={'w-full'}></div>
<div className={'w-full'}>
<PricingTable
config={billingConfig}
paths={{
signUp: pathsConfig.auth.signUp,
}}
/>
</div>
</div>
</div>
</div>

View File

@@ -43,7 +43,7 @@
"i18next": "^23.10.1",
"i18next-resources-to-backend": "^1.2.0",
"lucide-react": "^0.363.0",
"next": "14.2.0-canary.56",
"next": "14.2.0-canary.58",
"next-sitemap": "^4.2.3",
"next-themes": "0.3.0",
"react": "18.2.0",

View File

@@ -33,6 +33,7 @@
"proceedToPayment": "Proceed to Payment",
"startTrial": "Start Trial",
"perTeamMember": "Per team member",
"perUnit": "For each {{unit}}",
"perUnitIncluded": "({{included}} included)",
"featuresLabel": "Features",
"detailsLabel": "Details",

View File

@@ -12,16 +12,16 @@ export function LineItemDetails(
selectedInterval?: string | undefined;
}>,
) {
const className =
'flex items-center justify-between text-sm border-b border-dashed pb-2 last:border-transparent';
return (
<div className={'flex flex-col divide-y'}>
<div className={'flex flex-col space-y-2'}>
{props.lineItems.map((item) => {
switch (item.type) {
case 'base':
return (
<div
key={item.id}
className={'flex items-center justify-between py-1.5 text-sm'}
>
<div key={item.id} className={className}>
<span className={'flex space-x-2'}>
<span>
<Trans i18nKey={'billing:basePlan'} />
@@ -49,10 +49,7 @@ export function LineItemDetails(
case 'per-seat':
return (
<div
key={item.id}
className={'flex items-center justify-between py-1.5 text-sm'}
>
<div key={item.id} className={className}>
<span>
<Trans i18nKey={'billing:perTeamMember'} />
</span>
@@ -65,25 +62,26 @@ export function LineItemDetails(
case 'metered':
return (
<div
key={item.id}
className={'flex items-center justify-between py-1.5 text-sm'}
>
<span>
<Trans
i18nKey={'billing:perUnit'}
values={{
unit: item.unit,
}}
/>
{item.included ? (
<div key={item.id} className={className}>
<span className={'flex items-center space-x-2'}>
<span>
<Trans
i18nKey={'billing:perUnitIncluded'}
i18nKey={'billing:perUnit'}
values={{
included: item.included,
unit: item.unit,
}}
/>
</span>
{item.included ? (
<span>
<Trans
i18nKey={'billing:perUnitIncluded'}
values={{
included: item.included,
}}
/>
</span>
) : (
''
)}

View File

@@ -377,10 +377,14 @@ function PlanDetails({
}) {
const isRecurring = selectedPlan.paymentType === 'recurring';
// trick to force animation on re-render
const key = Math.random();
return (
<div
key={key}
className={
'fade-in animate-in zoom-in-90 flex w-full flex-col space-y-4 rounded-lg border p-4'
'fade-in animate-in flex w-full flex-col space-y-4 rounded-lg border p-4 duration-500'
}
>
<div className={'flex flex-col space-y-0.5'}>

View File

@@ -212,13 +212,11 @@ function PricingItem(
</If>
</div>
<div
className={cn({
['text-muted-foreground']: !highlighted,
['text-primary-foreground']: highlighted,
})}
>
<FeaturesList features={props.product.features} />
<div>
<FeaturesList
highlighted={highlighted}
features={props.product.features}
/>
</div>
</div>
@@ -245,13 +243,14 @@ function PricingItem(
function FeaturesList(
props: React.PropsWithChildren<{
features: string[];
highlighted?: boolean;
}>,
) {
return (
<ul className={'flex flex-col space-y-2'}>
{props.features.map((feature) => {
return (
<ListItem key={feature}>
<ListItem highlighted={props.highlighted} key={feature}>
<Trans
i18nKey={`common:plans.features.${feature}`}
defaults={feature}
@@ -279,14 +278,31 @@ function Price({ children }: React.PropsWithChildren) {
);
}
function ListItem({ children }: React.PropsWithChildren) {
function ListItem({
children,
highlighted,
}: React.PropsWithChildren<{
highlighted?: boolean;
}>) {
return (
<li className={'flex items-center space-x-1.5'}>
<div>
<CheckCircle className={'h-4 text-green-600'} />
<CheckCircle
className={cn('h-4', {
['text-primary-foreground']: highlighted,
['text-green-600']: !highlighted,
})}
/>
</div>
<span className={'text-sm'}>{children}</span>
<span
className={cn('text-sm', {
['text-muted-foreground']: !highlighted,
['text-primary-foreground']: highlighted,
})}
>
{children}
</span>
</li>
);
}

88
pnpm-lock.yaml generated
View File

@@ -97,7 +97,7 @@ importers:
version: 5.28.6(react@18.2.0)
'@tanstack/react-query-next-experimental':
specifier: ^5.28.14
version: 5.28.14(@tanstack/react-query@5.28.6)(next@14.2.0-canary.56)(react@18.2.0)
version: 5.28.14(@tanstack/react-query@5.28.6)(next@14.2.0-canary.58)(react@18.2.0)
'@tanstack/react-table':
specifier: ^8.15.3
version: 8.15.3(react-dom@18.2.0)(react@18.2.0)
@@ -106,7 +106,7 @@ importers:
version: 3.6.0
edge-csrf:
specifier: ^1.0.9
version: 1.0.9(next@14.2.0-canary.56)
version: 1.0.9(next@14.2.0-canary.58)
i18next:
specifier: ^23.10.1
version: 23.10.1
@@ -117,11 +117,11 @@ importers:
specifier: ^0.363.0
version: 0.363.0(react@18.2.0)
next:
specifier: 14.2.0-canary.56
version: 14.2.0-canary.56(react-dom@18.2.0)(react@18.2.0)
specifier: 14.2.0-canary.58
version: 14.2.0-canary.58(react-dom@18.2.0)(react@18.2.0)
next-sitemap:
specifier: ^4.2.3
version: 4.2.3(next@14.2.0-canary.56)
version: 4.2.3(next@14.2.0-canary.58)
next-themes:
specifier: 0.3.0
version: 0.3.0(react-dom@18.2.0)(react@18.2.0)
@@ -1102,7 +1102,7 @@ packages:
resolution: {integrity: sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.17.0
'@babel/types': 7.24.0
jsesc: 2.5.2
source-map: 0.5.7
dev: false
@@ -2263,8 +2263,8 @@ packages:
resolution: {integrity: sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==}
dev: false
/@next/env@14.2.0-canary.56:
resolution: {integrity: sha512-slHTSLx6xovPaNJd6j+SAgK3IZz0D4Go5Vj6hb7/UCYXii1G7xeVgO2EIHdwcuzNaeuug8iN6wvpqS9qjH67cA==}
/@next/env@14.2.0-canary.58:
resolution: {integrity: sha512-mEDmzHhOHKGbd/qv8CAc8JGkPrbGs2txWz9Y2XHew77HUTmOsrzSKDK467cYa35r18KcGwftZPRv3s7EfW4Kxg==}
dev: false
/@next/eslint-plugin-next@14.1.4:
@@ -2291,8 +2291,8 @@ packages:
dev: false
optional: true
/@next/swc-darwin-arm64@14.2.0-canary.56:
resolution: {integrity: sha512-9d162Qzls1eDrw2a7e6IiK5bzBm2LVD5Fh2DP67rggPFqgl15hJMDfjv+vfiCbFhxaA95uv45S48Kj/X2p4Wrg==}
/@next/swc-darwin-arm64@14.2.0-canary.58:
resolution: {integrity: sha512-NZwWdgltCBHRBBvK+ioEKv4Mcj/PEc/5uowXAUpirhATCB0n4meAluamSRcWcmZckG08zIutfocCz9hHWeYUxA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
@@ -2318,8 +2318,8 @@ packages:
dev: false
optional: true
/@next/swc-darwin-x64@14.2.0-canary.56:
resolution: {integrity: sha512-c3/9yRBCpbt5dF7KzdoI9gH4IMMciAaH1GHf97UOK7cuI7/ctvlld7X1IP+HlMnd8+p3+FHkjySUM/Rm+t//Mw==}
/@next/swc-darwin-x64@14.2.0-canary.58:
resolution: {integrity: sha512-zv/iMoVZoyB9PxNSSNKY0p3Jg7a1ezVXFkFHLbPvqRCOxvgfkLIpdOJ6QAGBOknFF8qfQCIhRYQXbijto4WH+g==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
@@ -2345,8 +2345,8 @@ packages:
dev: false
optional: true
/@next/swc-linux-arm64-gnu@14.2.0-canary.56:
resolution: {integrity: sha512-Pv83XZ/Fyk6uz6pDA6Uywp2LT7+E9IXJtWgHXp0rsLTjSuyvXz76kEX9ZoQrakhMRF3ki4+f1AXysPkehuazNQ==}
/@next/swc-linux-arm64-gnu@14.2.0-canary.58:
resolution: {integrity: sha512-4Gyb6EO4PokA/tqZsZfR38t4UOMl2w0LpYZfhfBoJ4jiPXW5RymgDcJE30LKM1f2k+E69TnxyUjD18Z6RnONiw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
@@ -2372,8 +2372,8 @@ packages:
dev: false
optional: true
/@next/swc-linux-arm64-musl@14.2.0-canary.56:
resolution: {integrity: sha512-ytP9AAbMYXIye6dQ1RoFV7Eb2k+yu+nMlny4COYMWhNto+30dx0mmNjjJ464c7XU5KvcLTqdj2pcBGFi2Uj0vw==}
/@next/swc-linux-arm64-musl@14.2.0-canary.58:
resolution: {integrity: sha512-8Ku+EyiCK9VNz/lV8Yhhtw8QV0z0U1xa+m5ShqpvpyTVOv/q4JerSQ3JivzrU1T4sUUO7jb7Pu3+/nfFIXq0Tw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
@@ -2399,8 +2399,8 @@ packages:
dev: false
optional: true
/@next/swc-linux-x64-gnu@14.2.0-canary.56:
resolution: {integrity: sha512-/V6ngDidzDYkK8120PfRWDCi/26y9WywaZ/lWJY+345sXaB3CGLnFd3tyfdIpzHxDOvRYDHCTLh8lYd0XJF+uA==}
/@next/swc-linux-x64-gnu@14.2.0-canary.58:
resolution: {integrity: sha512-G1BpyRalWUBak4WDych1cQ90LZAh2rYl0dOTLrMWkrJ1KYD06gY18Ty+RD/hevOdk/1gXHs8Uep6wgwc9EmzPg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
@@ -2426,8 +2426,8 @@ packages:
dev: false
optional: true
/@next/swc-linux-x64-musl@14.2.0-canary.56:
resolution: {integrity: sha512-YEwoiErfzmmXRrqoInPDItJ0X+PZbeTQVkR9UpYgUstgrwr0/aFILLI/wLT52r9NWX3yMiqONB/Owv5LefkQlg==}
/@next/swc-linux-x64-musl@14.2.0-canary.58:
resolution: {integrity: sha512-l5ggp3U9PIlBPg9n5jTt0EZWUxQ7nWi/ObYBWX1EYHU9CjNwZ/ka01nWoMYqenI3wuAnb4D8ORgAvUv9JrKHhA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
@@ -2453,8 +2453,8 @@ packages:
dev: false
optional: true
/@next/swc-win32-arm64-msvc@14.2.0-canary.56:
resolution: {integrity: sha512-gEIxu949cO8xTnapS5p+EVg3fr8dzQgsybjIVC/FIl8dfBDMMHHiUIJm2lNUvi9zRc4OgrJ7WC+0tA58h9JRfA==}
/@next/swc-win32-arm64-msvc@14.2.0-canary.58:
resolution: {integrity: sha512-QKp5UAA094uQ2Oz9j5WtscvXYfrVjMytn1BF+O/YpwmUTNKAvx+9DZ1KqaRLoQ02Pnwsbz9DcF7oMowxE4OhRQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
@@ -2480,8 +2480,8 @@ packages:
dev: false
optional: true
/@next/swc-win32-ia32-msvc@14.2.0-canary.56:
resolution: {integrity: sha512-3EYXk812fRXuwhID9IYG+xodNr25IPkoEbCLTdKOzS8okZrRzRHo+WmhIqF2ylS4LDFt18yVWGibN2pPJISjVg==}
/@next/swc-win32-ia32-msvc@14.2.0-canary.58:
resolution: {integrity: sha512-BHJoVmarYdw3SqAVWqKA6ro6cak5XmeZcMsK9PIjVB3MoWkfY7bdWPoIGmzX/jfSGi8OibWY7bF2o5DddZjvSg==}
engines: {node: '>= 10'}
cpu: [ia32]
os: [win32]
@@ -2507,8 +2507,8 @@ packages:
dev: false
optional: true
/@next/swc-win32-x64-msvc@14.2.0-canary.56:
resolution: {integrity: sha512-FvsUo8nh9Hc6qvK0uqoinEfZbw+q16Jj6qewA0fdUQ+QY0i6ECo7c8Wsc6Jm/dGmW/CAA1zAVUX00L9h+MGyZw==}
/@next/swc-win32-x64-msvc@14.2.0-canary.58:
resolution: {integrity: sha512-zoMWDNjZ/CXQF7Vz0UrsiWpTlQPbHwfO285/vhiUjaPv3QxX2eGHqUYQi7jrI593yUq01bOqrft8Ho66dlmEWw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
@@ -4999,7 +4999,7 @@ packages:
/@tanstack/query-core@5.28.6:
resolution: {integrity: sha512-hnhotV+DnQtvtR3jPvbQMPNMW4KEK0J4k7c609zJ8muiNknm+yoDyMHmxTWM5ZnlZpsz0zOxYFr+mzRJNHWJsA==}
/@tanstack/react-query-next-experimental@5.28.14(@tanstack/react-query@5.28.6)(next@14.2.0-canary.56)(react@18.2.0):
/@tanstack/react-query-next-experimental@5.28.14(@tanstack/react-query@5.28.6)(next@14.2.0-canary.58)(react@18.2.0):
resolution: {integrity: sha512-gGHx3uJkZNYYpFNFk8eEo96ssiFE2OmYA49wszHxHrtO5nL7kzRcnJF8SALGpqSEjo5D3fLMH24MrhbBsO0sig==}
peerDependencies:
'@tanstack/react-query': ^5.28.14
@@ -5007,7 +5007,7 @@ packages:
react: ^18.0.0
dependencies:
'@tanstack/react-query': 5.28.6(react@18.2.0)
next: 14.2.0-canary.56(react-dom@18.2.0)(react@18.2.0)
next: 14.2.0-canary.58(react-dom@18.2.0)(react@18.2.0)
react: 18.2.0
dev: false
@@ -6819,12 +6819,12 @@ packages:
/eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
/edge-csrf@1.0.9(next@14.2.0-canary.56):
/edge-csrf@1.0.9(next@14.2.0-canary.58):
resolution: {integrity: sha512-3F89YTh42UDdISr3s9AEcgJDLi4ysgjGfnybzF0LuZGaG2W31h1ZwgWwEQBLMj04lAklcP4XHZYi7vk9o8zcbg==}
peerDependencies:
next: ^13.0.0 || ^14.0.0
dependencies:
next: 14.2.0-canary.56(react-dom@18.2.0)(react@18.2.0)
next: 14.2.0-canary.58(react-dom@18.2.0)(react@18.2.0)
dev: false
/editorconfig@1.0.4:
@@ -9609,7 +9609,7 @@ packages:
- supports-color
dev: false
/next-sitemap@4.2.3(next@14.2.0-canary.56):
/next-sitemap@4.2.3(next@14.2.0-canary.58):
resolution: {integrity: sha512-vjdCxeDuWDzldhCnyFCQipw5bfpl4HmZA7uoo3GAaYGjGgfL4Cxb1CiztPuWGmS+auYs7/8OekRS8C2cjdAsjQ==}
engines: {node: '>=14.18'}
hasBin: true
@@ -9620,7 +9620,7 @@ packages:
'@next/env': 13.5.6
fast-glob: 3.3.2
minimist: 1.2.8
next: 14.2.0-canary.56(react-dom@18.2.0)(react@18.2.0)
next: 14.2.0-canary.58(react-dom@18.2.0)(react@18.2.0)
dev: false
/next-themes@0.3.0(react-dom@18.2.0)(react@18.2.0):
@@ -9712,8 +9712,8 @@ packages:
- babel-plugin-macros
dev: false
/next@14.2.0-canary.56(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-o5/GGmNwGY3y3At/K9Y/9Vmuhjk7lwXPh7W/feePYeqpYu7/jp47NDg+EKczNj3ueOdKPFJr2kiwYfD3rT2RBQ==}
/next@14.2.0-canary.58(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-7aphi4r1S37J19QQprflzTHOfCXAWUd8AmtfkLzBtPPTkhsbEikEXdFHvo2c5DUgYTvFf7teBIxS6Vi2m08byg==}
engines: {node: '>=18.17.0'}
hasBin: true
peerDependencies:
@@ -9730,7 +9730,7 @@ packages:
sass:
optional: true
dependencies:
'@next/env': 14.2.0-canary.56
'@next/env': 14.2.0-canary.58
'@swc/helpers': 0.5.5
busboy: 1.6.0
caniuse-lite: 1.0.30001600
@@ -9740,15 +9740,15 @@ packages:
react-dom: 18.2.0(react@18.2.0)
styled-jsx: 5.1.1(react@18.2.0)
optionalDependencies:
'@next/swc-darwin-arm64': 14.2.0-canary.56
'@next/swc-darwin-x64': 14.2.0-canary.56
'@next/swc-linux-arm64-gnu': 14.2.0-canary.56
'@next/swc-linux-arm64-musl': 14.2.0-canary.56
'@next/swc-linux-x64-gnu': 14.2.0-canary.56
'@next/swc-linux-x64-musl': 14.2.0-canary.56
'@next/swc-win32-arm64-msvc': 14.2.0-canary.56
'@next/swc-win32-ia32-msvc': 14.2.0-canary.56
'@next/swc-win32-x64-msvc': 14.2.0-canary.56
'@next/swc-darwin-arm64': 14.2.0-canary.58
'@next/swc-darwin-x64': 14.2.0-canary.58
'@next/swc-linux-arm64-gnu': 14.2.0-canary.58
'@next/swc-linux-arm64-musl': 14.2.0-canary.58
'@next/swc-linux-x64-gnu': 14.2.0-canary.58
'@next/swc-linux-x64-musl': 14.2.0-canary.58
'@next/swc-win32-arm64-msvc': 14.2.0-canary.58
'@next/swc-win32-ia32-msvc': 14.2.0-canary.58
'@next/swc-win32-x64-msvc': 14.2.0-canary.58
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros