mirror of
https://github.com/vernu/textbee.git
synced 2026-09-03 03:29:58 +03:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac65907453 | ||
|
|
d8460bcb8b | ||
|
|
eb94085f6e |
@@ -306,11 +306,14 @@ export class BillingService {
|
||||
}
|
||||
|
||||
try {
|
||||
const discount = await this.polarApi.discounts.get({
|
||||
id: discountId,
|
||||
})
|
||||
if (discount) {
|
||||
checkoutOptions.discountId = discount.id
|
||||
let discount = null;
|
||||
if (discountId) {
|
||||
discount = await this.polarApi.discounts.get({
|
||||
id: discountId,
|
||||
})
|
||||
if (discount) {
|
||||
checkoutOptions.discountId = discount.id
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('failed to get discount', error)
|
||||
|
||||
@@ -4,77 +4,40 @@
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1.0' />
|
||||
<title>Account Deletion Request</title>
|
||||
<style>
|
||||
body { font-family: 'Helvetica Neue', Arial, sans-serif; line-height: 1.6;
|
||||
color: #333; max-width: 600px; margin: 0 auto; padding: 20px; } .header {
|
||||
text-align: center; margin-bottom: 20px; } .logo { max-width: 150px;
|
||||
margin-bottom: 10px; } h1 { color: #dc2626; margin-bottom: 20px; }
|
||||
.content { background-color: #f9fafb; border-radius: 8px; padding: 20px;
|
||||
margin-bottom: 20px; } .message-details { background-color: #ffffff;
|
||||
border-left: 4px solid #dc2626; padding: 15px; margin: 15px 0;
|
||||
border-radius: 4px; } .contact-info { margin-top: 20px; padding-top: 15px;
|
||||
border-top: 1px solid #e5e7eb; } .field-label { font-weight: bold; color:
|
||||
#4b5563; margin-bottom: 5px; } .footer { text-align: center; font-size:
|
||||
14px; color: #6b7280; margin-top: 30px; padding-top: 20px; border-top: 1px
|
||||
solid #e5e7eb; } .important-notice { background-color: #fee2e2;
|
||||
border-left: 4px solid #dc2626; padding: 15px; margin: 15px 0;
|
||||
border-radius: 4px; } .cancel-notice { background-color: #e0f2fe; border:
|
||||
2px solid #0284c7; padding: 15px; margin: 20px 0; border-radius: 4px;
|
||||
text-align: center; } .cancel-notice h3 { color: #0284c7; margin-top: 0; }
|
||||
.cancel-action { font-weight: bold; font-size: 16px; } .cancel-button {
|
||||
display: inline-block; margin-top: 10px; padding: 8px 16px;
|
||||
background-color: #0284c7; color: white; border-radius: 4px;
|
||||
text-decoration: none; font-weight: bold; }
|
||||
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px; }
|
||||
h1 { color: #dc2626; }
|
||||
.notice { background: #fee2e2; border-left: 4px solid #dc2626; padding: 15px; margin: 15px 0; }
|
||||
.cancel { background: #e0f2fe; border: 2px solid #0284c7; padding: 15px; margin: 20px 0; text-align: center; }
|
||||
.footer { text-align: center; font-size: 14px; color: #6b7280; margin-top: 30px; padding-top: 20px; border-top: 1px solid #e5e7eb; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class='header'>
|
||||
{{!-- <img src="{{appLogoUrl}}" alt="TextBee Logo" class="logo"> --}}
|
||||
<h1>Account Deletion Request</h1>
|
||||
<h1>Account Deletion Request</h1>
|
||||
|
||||
<p>Hello {{name}},</p>
|
||||
|
||||
<p>We have received your request to delete your TextBee account. We're sorry to see you go.</p>
|
||||
|
||||
<div class='notice'>
|
||||
<p><strong>Important:</strong> Your account has been marked for deletion and will be processed within 7 days. During this period:</p>
|
||||
<ul>
|
||||
<li>You can still log in and access your account until the deletion is completed</li>
|
||||
<li>After the deletion is complete, all your data will be permanently removed</li>
|
||||
<li>This action cannot be undone once processed</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class='content'>
|
||||
<p>Hello {{name}},</p>
|
||||
<p><strong>Reason for deletion:</strong> {{#if message}}{{message}}{{else}}No reason provided{{/if}}</p>
|
||||
|
||||
<p>We have received your request to delete your TextBee account. We're
|
||||
sorry to see you go.</p>
|
||||
<p><strong>Account:</strong> {{name}} ({{email}})</p>
|
||||
|
||||
<div class='important-notice'>
|
||||
<p><strong>Important:</strong>
|
||||
Your account has been marked for deletion and will be processed within
|
||||
7 days. During this period:</p>
|
||||
<ul>
|
||||
<li>You can still log in and access your account until the deletion is
|
||||
completed</li>
|
||||
<li>After the deletion is complete, all your data will be permanently
|
||||
removed</li>
|
||||
<li>This action cannot be undone once processed</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class='message-details'>
|
||||
<div class='field-label'>Reason for deletion:</div>
|
||||
<p>{{#if message}}{{message}}{{else}}No reason provided{{/if}}</p>
|
||||
</div>
|
||||
|
||||
<div class='contact-info'>
|
||||
<div class='field-label'>Account Information:</div>
|
||||
<p>Name: {{name}}</p>
|
||||
<p>Email: {{email}}</p>
|
||||
</div>
|
||||
|
||||
<div class='cancel-notice'>
|
||||
<h3>Changed Your Mind?</h3>
|
||||
<p class='cancel-action'>If you didn't request this deletion or want to
|
||||
keep your account, you can easily cancel this request!</p>
|
||||
<p>Simply reply to this email as soon as possible and we'll immediately
|
||||
stop the deletion process.</p>
|
||||
<p>Your account and all your data will remain intact. No further action
|
||||
will be needed.</p>
|
||||
</div>
|
||||
<div class='cancel'>
|
||||
<h3 style='color: #0284c7; margin-top: 0;'>Changed Your Mind?</h3>
|
||||
<p>If you didn't request this deletion or want to keep your account, simply reply to this email and we'll immediately stop the deletion process.</p>
|
||||
</div>
|
||||
|
||||
<div class='footer'>
|
||||
<p>© {{currentYear}} textBee.dev.</p>
|
||||
<p>© {{currentYear}} textbee.dev.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -4,58 +4,32 @@
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1.0' />
|
||||
<title>Support Request Confirmation</title>
|
||||
<style>
|
||||
body { font-family: 'Helvetica Neue', Arial, sans-serif; line-height: 1.6;
|
||||
color: #333; max-width: 600px; margin: 0 auto; padding: 20px; } .header {
|
||||
text-align: center; margin-bottom: 20px; } .logo { max-width: 150px;
|
||||
margin-bottom: 10px; } h1 { color: #2563eb; margin-bottom: 20px; }
|
||||
.content { background-color: #f9fafb; border-radius: 8px; padding: 20px;
|
||||
margin-bottom: 20px; } .message-details { background-color: #ffffff;
|
||||
border-left: 4px solid #2563eb; padding: 15px; margin: 15px 0;
|
||||
border-radius: 4px; } .contact-info { margin-top: 20px; padding-top: 15px;
|
||||
border-top: 1px solid #e5e7eb; } .field-label { font-weight: bold; color:
|
||||
#4b5563; margin-bottom: 5px; } .footer { text-align: center; font-size:
|
||||
14px; color: #6b7280; margin-top: 30px; padding-top: 20px; border-top: 1px
|
||||
solid #e5e7eb; }
|
||||
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px; }
|
||||
h1 { color: #2563eb; }
|
||||
.details { background: #ffffff; border-left: 4px solid #2563eb; padding: 15px; margin: 15px 0; }
|
||||
.footer { text-align: center; font-size: 14px; color: #6b7280; margin-top: 30px; padding-top: 20px; border-top: 1px solid #e5e7eb; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class='header'>
|
||||
{{!-- <img src="{{appLogoUrl}}" alt="TextBee Logo" class="logo"> --}}
|
||||
<h1>Support Request Submitted</h1>
|
||||
<h1>Support Request Submitted</h1>
|
||||
|
||||
<p>Hello {{name}},</p>
|
||||
|
||||
<p>Thank you for contacting our support team. We have received your message and will get back to you as soon as possible.</p>
|
||||
|
||||
<div class='details'>
|
||||
<p><strong>Category:</strong> {{category}}</p>
|
||||
<p><strong>Your Message:</strong></p>
|
||||
<p>{{message}}</p>
|
||||
</div>
|
||||
|
||||
<div class='content'>
|
||||
<p>Hello {{name}},</p>
|
||||
<p><strong>Your Contact Information:</strong></p>
|
||||
<p>Name: {{name}}<br />Email: {{email}}<br />Phone: {{#if phone}}{{phone}}{{else}}Not provided{{/if}}</p>
|
||||
|
||||
<p>Thank you for contacting our support team. We have received your
|
||||
message and will get back to you as soon as possible.</p>
|
||||
|
||||
<div class='message-details'>
|
||||
<div class='field-label'>Category:</div>
|
||||
<p>{{category}}</p>
|
||||
|
||||
<div class='field-label'>Your Message:</div>
|
||||
<p>{{message}}</p>
|
||||
</div>
|
||||
|
||||
<div class='contact-info'>
|
||||
<div class='field-label'>Your Contact Information:</div>
|
||||
<p>Name: {{name}}</p>
|
||||
<p>Email: {{email}}</p>
|
||||
{{#if phone}}
|
||||
<p>Phone: {{phone}}</p>
|
||||
{{else}}
|
||||
<p>Phone: Not provided</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<p>we will review your request and respond to the email address you
|
||||
provided. If you have any additional information to share, please reply
|
||||
to this email.</p>
|
||||
</div>
|
||||
<p>We will review your request and respond to the email address you provided. If you have any additional information to share, please reply to this email.</p>
|
||||
|
||||
<div class='footer'>
|
||||
<p>© {{currentYear}} textBee.dev.</p>
|
||||
<p>© {{currentYear}} textbee.dev.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -6,6 +6,20 @@ import { useQuery } from '@tanstack/react-query'
|
||||
import Link from 'next/link'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
const DISCOUNT_CODE_FALLBACK = null
|
||||
const DISCOUNT_PERCENTAGE_FALLBACK = null
|
||||
|
||||
const envDiscountCode = process.env.NEXT_PUBLIC_DISCOUNT_CODE?.trim()
|
||||
const envDiscountPercentage = process.env.NEXT_PUBLIC_DISCOUNT_PERCENTAGE?.trim()
|
||||
|
||||
const discountCode = (envDiscountCode !== undefined && envDiscountCode !== '')
|
||||
? envDiscountCode
|
||||
: DISCOUNT_CODE_FALLBACK
|
||||
const discountPercentage = (envDiscountPercentage !== undefined && envDiscountPercentage !== '')
|
||||
? envDiscountPercentage
|
||||
: DISCOUNT_PERCENTAGE_FALLBACK
|
||||
const isDiscountEnabled = discountCode !== null && discountCode !== '' && discountPercentage !== null && discountPercentage !== ''
|
||||
|
||||
export default function UpgradeToProAlert() {
|
||||
const {
|
||||
data: currentSubscription,
|
||||
@@ -43,7 +57,7 @@ export default function UpgradeToProAlert() {
|
||||
urgency: 'warning'
|
||||
}
|
||||
} else {
|
||||
const ctaMessages = [
|
||||
const allCtaMessages = [
|
||||
"Upgrade to Pro for exclusive features and benefits!",
|
||||
"Offer: You are eligible for a 30% discount when upgrading to Pro!",
|
||||
"Unlock premium features with our Pro plan today!",
|
||||
@@ -51,7 +65,7 @@ export default function UpgradeToProAlert() {
|
||||
"Pro users get priority support and advanced features!",
|
||||
"Limited time offer: Upgrade to Pro and save 30%!",
|
||||
]
|
||||
const buttonTexts = [
|
||||
const allButtonTexts = [
|
||||
"Get Pro Now!",
|
||||
"Upgrade Today!",
|
||||
"Go Pro!",
|
||||
@@ -59,12 +73,36 @@ export default function UpgradeToProAlert() {
|
||||
"Claim Your Discount!",
|
||||
"Upgrade & Save!",
|
||||
]
|
||||
|
||||
// Filter out discount-related messages if discount is not enabled
|
||||
const ctaMessages = isDiscountEnabled
|
||||
? allCtaMessages
|
||||
: allCtaMessages.filter(
|
||||
(msg) =>
|
||||
!msg.toLowerCase().includes('discount') &&
|
||||
!msg.toLowerCase().includes('offer') &&
|
||||
!msg.toLowerCase().includes('save') &&
|
||||
!msg.includes('30%')
|
||||
)
|
||||
|
||||
const buttonTexts = isDiscountEnabled
|
||||
? allButtonTexts
|
||||
: allButtonTexts.filter(
|
||||
(text) =>
|
||||
!text.toLowerCase().includes('discount') &&
|
||||
!text.toLowerCase().includes('save')
|
||||
)
|
||||
|
||||
const randomIndex = Math.floor(Math.random() * ctaMessages.length)
|
||||
|
||||
const subMessage = isDiscountEnabled
|
||||
? `Use discount code ${discountCode} at checkout for a ${discountPercentage}% discount!`
|
||||
: "Unlock premium features, priority support, and advanced capabilities with Pro!"
|
||||
|
||||
return {
|
||||
bgColor: 'bg-gradient-to-r from-purple-500 to-pink-500',
|
||||
message: ctaMessages[randomIndex],
|
||||
subMessage: `Use discount code SAVE30P at checkout for a 30% discount!`,
|
||||
subMessage,
|
||||
buttonText: buttonTexts[randomIndex],
|
||||
buttonColor: 'bg-red-500 text-white hover:bg-red-600 border-red-500',
|
||||
urgency: 'normal'
|
||||
@@ -87,8 +125,8 @@ export default function UpgradeToProAlert() {
|
||||
{alertConfig.message}
|
||||
</span>
|
||||
<span className='w-full sm:flex-1 text-center sm:text-left text-xs md:text-sm'>
|
||||
{alertConfig.urgency === 'normal' ? (
|
||||
<>Use discount code <strong className="text-yellow-200">SAVE30P</strong> at checkout for a 30% discount!</>
|
||||
{alertConfig.urgency === 'normal' && isDiscountEnabled ? (
|
||||
<>Use discount code <strong className="text-yellow-200">{discountCode}</strong> at checkout for a {discountPercentage}% discount!</>
|
||||
) : (
|
||||
alertConfig.subMessage
|
||||
)}
|
||||
|
||||
@@ -53,7 +53,7 @@ export default function DashboardLayout({
|
||||
<div className='space-y-2 p-4'>
|
||||
<VerifyEmailAlert />
|
||||
<AccountDeletionAlert />
|
||||
{/* <UpgradeToProAlert /> */}
|
||||
<UpgradeToProAlert />
|
||||
{/* <BlackFridayModal /> */}
|
||||
</div>
|
||||
{children}
|
||||
|
||||
Reference in New Issue
Block a user