feat(env): add BOT_URL to environment variables and update related configurations

- Introduced BOT_URL to the environment schema for enhanced configuration management.
- Updated turbo.json to include BOT_URL in the environment variables list.
- Modified subscription-bar.tsx to improve user messaging for subscription availability.
This commit is contained in:
vchikalkin 2025-09-02 16:55:41 +03:00
parent ce75f0c13d
commit edf892e9ec
6 changed files with 109 additions and 3 deletions

View File

@ -0,0 +1,73 @@
import { getSubscription } from '@/actions/api/subscriptions';
import { getSessionUser } from '@/actions/session';
import { TryFreeButton } from '@/components/subscription';
import { env } from '@/config/env';
import { Button } from '@repo/ui/components/ui/button';
import { ArrowRight, Crown } from 'lucide-react';
export default async function ProPage() {
const { telegramId } = await getSessionUser();
const subscriptionData = await getSubscription({ telegramId });
// Простая логика для проверки статуса подписки
const subscription = subscriptionData?.subscription;
const isActive =
subscription?.isActive &&
subscription?.expiresAt &&
new Date() < new Date(subscription.expiresAt);
// Проверка возможности использования пробного периода
const hasUsedTrial = subscription?.subscriptionHistories?.some(
(item) => item && item.period === 'trial' && item.state === 'success',
);
const canUseTrial = !isActive && !hasUsedTrial;
return (
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-indigo-100 dark:from-slate-900 dark:via-slate-800 dark:to-slate-900">
{/* Hero Section */}
<div className="px-4 py-16 sm:px-6 lg:px-8">
<div className="mx-auto max-w-4xl text-center">
<div className="mb-8 flex justify-center">
<div className="relative">
<div className="absolute inset-0 rounded-full bg-gradient-to-r from-purple-600 to-blue-600 opacity-30 blur-xl" />
<div className="relative rounded-full bg-gradient-to-r from-purple-600 to-blue-600 p-4">
<Crown className="size-8 text-white" />
</div>
</div>
</div>
<h1 className="mb-6 text-4xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-6xl">
Подписка{' '}
<span className="bg-gradient-to-r from-purple-600 to-blue-600 bg-clip-text text-transparent">
Pro
</span>
</h1>
<p className="mx-auto mb-8 max-w-2xl text-xl text-gray-600 dark:text-gray-300">
{isActive
? 'Ваша подписка Pro активна! Доступно неограниченное количество записей'
: 'Разблокируйте неограниченное количество записей в месяц'}
</p>
{!isActive && (
<div className="flex flex-col items-center justify-center gap-4 sm:flex-row">
{canUseTrial && <TryFreeButton />}
<Button
asChild
className="w-full border-2 border-gray-300 text-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700 sm:w-auto"
size="lg"
variant="outline"
>
<a href={env.BOT_URL} rel="noopener noreferrer" target="_blank">
Оформить подписку через бота
<ArrowRight className="ml-2 size-5" />
</a>
</Button>
</div>
)}
</div>
</div>
</div>
);
}

View File

@ -24,7 +24,7 @@ export function SubscriptionInfoBar() {
}
if (!isLoading && remainingOrdersCount && maxOrdersPerMonth) {
description = `Осталось ${remainingOrdersCount} из ${maxOrdersPerMonth} записей в этом месяце`;
description = `Доступно ${remainingOrdersCount} из ${maxOrdersPerMonth} записей в этом месяце`;
}
return (

View File

@ -0,0 +1 @@
export * from './try-free-button';

View File

@ -0,0 +1,25 @@
'use client';
import { Button } from '@repo/ui/components/ui/button';
import { Sparkles } from 'lucide-react';
type TryFreeButtonProps = {
readonly className?: string;
readonly size?: 'default' | 'lg';
};
export function TryFreeButton({ className = '', size = 'lg' }: TryFreeButtonProps) {
// eslint-disable-next-line unicorn/consistent-function-scoping
const handleTryFree = () => {};
return (
<Button
className={`w-full bg-gradient-to-r from-purple-600 to-blue-600 px-8 py-3 text-lg font-semibold text-white shadow-lg transition-all duration-200 hover:from-purple-700 hover:to-blue-700 hover:shadow-xl sm:w-auto ${className}`}
onClick={handleTryFree}
size={size}
>
<Sparkles className="mr-2 size-5" />
Попробовать бесплатно
</Button>
);
}

View File

@ -3,7 +3,7 @@ import { z } from 'zod';
export const envSchema = z.object({
__DEV_TELEGRAM_ID: z.string().default(''),
BOT_TOKEN: z.string(),
BOT_URL: z.string(),
});
export const env = envSchema.parse(process.env);

View File

@ -6,7 +6,14 @@
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": [".next/**", "!.next/cache/**"],
"env": ["URL_GRAPHQL", "PASSWORD_GRAPHQL", "LOGIN_GRAPHQL", "BOT_TOKEN", "NEXTAUTH_SECRET"]
"env": [
"URL_GRAPHQL",
"PASSWORD_GRAPHQL",
"LOGIN_GRAPHQL",
"BOT_TOKEN",
"NEXTAUTH_SECRET",
"BOT_URL"
]
},
"lint": {
"dependsOn": ["^lint"]