From d3d4a69c47ae4688837b17372b5902ecdcdb479b Mon Sep 17 00:00:00 2001 From: jaaaaavier Date: Thu, 12 Feb 2026 09:44:11 +0100 Subject: [PATCH 1/3] feat: new partners LP for bjoern & lefiltre --- src/hooks/useSpecialOfferConfig.ts | 4 ++++ src/lib/types/index.ts | 2 ++ src/pages/[filename].tsx | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/hooks/useSpecialOfferConfig.ts b/src/hooks/useSpecialOfferConfig.ts index 1e8b2ab8b..6d4889b5a 100644 --- a/src/hooks/useSpecialOfferConfig.ts +++ b/src/hooks/useSpecialOfferConfig.ts @@ -26,6 +26,8 @@ export const ALLOWED_PATHS = [ 'simon42', 'devopstoolbox', 'heisect', + 'bjoern', + 'lefiltre', ]; export const ALTERNATE_RECOMENDATED_PLAN_PATHS = new Set([]); export const DARK_MODE_PATHS = new Set(['baity', 'xavier', 'oscar', 'rimembah', 'believemy', 'ghareeb']); @@ -54,6 +56,8 @@ export const COUPON_CODES = { simon42: PromoCodeName.simon42, devopstoolbox: PromoCodeName.devopstoolbox, heisect: PromoCodeName.heisect, + bjoern: PromoCodeName.bjoern, + lefiltre: PromoCodeName.lefiltre, }; interface OfferConfig { diff --git a/src/lib/types/index.ts b/src/lib/types/index.ts index 0877dc0be..abe6ec7f2 100644 --- a/src/lib/types/index.ts +++ b/src/lib/types/index.ts @@ -206,6 +206,8 @@ export enum PromoCodeName { love = 'LOVE88', heisect = 'HEISECT', devopstoolbox = 'DEVOPSTOOLBOX', + bjoern = 'BJOERN', + lefiltre = 'LEFILTRE', } export interface PromoCodeProps { diff --git a/src/pages/[filename].tsx b/src/pages/[filename].tsx index 1c305e5b0..d4f6cb2bc 100644 --- a/src/pages/[filename].tsx +++ b/src/pages/[filename].tsx @@ -72,6 +72,8 @@ const LANG_MAP = { simon42: 'de', heisect: 'de', devopstoolbox: 'en', + bjoern: 'de', + lefiltre: 'fr', }; function CombinedSpecialOffer({ From 6f31f7105d2f14e9061187ac81ff18b6f5705f8b Mon Sep 17 00:00:00 2001 From: jaaaaavier Date: Thu, 12 Feb 2026 10:39:52 +0100 Subject: [PATCH 2/3] feat: cloudoff afilliate --- .../shared/pricing/PricingSection.tsx | 56 ++++++++++++------- .../shared/pricing/PricingSectionWrapper.tsx | 6 ++ src/hooks/useSpecialOfferConfig.ts | 20 +++++++ src/lib/types/index.ts | 1 + src/pages/[filename].tsx | 26 +++++++-- 5 files changed, 83 insertions(+), 26 deletions(-) diff --git a/src/components/shared/pricing/PricingSection.tsx b/src/components/shared/pricing/PricingSection.tsx index 664f0f455..0414b9dd0 100644 --- a/src/components/shared/pricing/PricingSection.tsx +++ b/src/components/shared/pricing/PricingSection.tsx @@ -49,6 +49,8 @@ interface PriceTableProps { onBusinessPlansSelected?: (isBusiness: boolean) => void; differentRecommended?: boolean; isValentinesMode?: boolean; + onlyUltimatePlan?: boolean; + premiumAndUltimatePlan?: boolean; } export const PricingSection = ({ @@ -81,6 +83,8 @@ export const PricingSection = ({ showPromo, isAffiliate, isValentinesMode = false, + onlyUltimatePlan = false, + premiumAndUltimatePlan = false, }: PriceTableProps): JSX.Element => { const banner = require('@/assets/lang/en/banners.json'); @@ -183,28 +187,40 @@ export const PricingSection = ({ enterTo="scale-100 translate-y-0 opacity-100" className="flex flex-col gap-4" > -
+
{products?.individuals - ? products.individuals[billingFrequency].map((product, cardIndex) => ( - { + if (premiumAndUltimatePlan) { + return product.storage === '5TB' || product.storage === '3TB'; } - lang={lang} - darkMode={darkMode} - isAffiliate={isAffiliate} - cardIndex={cardIndex} - showGift={showPromo} - isValentinesMode={isValentinesMode} - /> - )) + if (onlyUltimatePlan) { + return product.storage === '5TB'; + } + return true; + }) + .map((product, cardIndex) => ( + + )) : undefined}
diff --git a/src/components/shared/pricing/PricingSectionWrapper.tsx b/src/components/shared/pricing/PricingSectionWrapper.tsx index fb23e597a..6be921e38 100644 --- a/src/components/shared/pricing/PricingSectionWrapper.tsx +++ b/src/components/shared/pricing/PricingSectionWrapper.tsx @@ -71,6 +71,8 @@ interface PricingSectionWrapperProps { overrideOnBusinessSwitchToggled?: (interval: Interval) => void; differentRecommended?: boolean; SectionTag?: React.ElementType; + onlyUltimatePlan?: boolean; + premiumAndUltimatePlan?: boolean; } const calculateDiscountPercentage = (decimalValue?: number) => { @@ -194,6 +196,8 @@ export const PricingSectionWrapper = ({ overrideOnBusinessSwitchToggled, differentRecommended, SectionTag = DEFAULTS.SectionTag, + onlyUltimatePlan = false, + premiumAndUltimatePlan = false, }: PricingSectionWrapperProps): JSX.Element => { const localPlanSelection = usePlanSelection( startFromPlan, @@ -280,6 +284,8 @@ export const PricingSectionWrapper = ({ differentRecommended={differentRecommended} showPromo={showPromo} isValentinesMode={isValentinesMode} + onlyUltimatePlan={onlyUltimatePlan} + premiumAndUltimatePlan={premiumAndUltimatePlan} />
diff --git a/src/hooks/useSpecialOfferConfig.ts b/src/hooks/useSpecialOfferConfig.ts index 6d4889b5a..5b698ad76 100644 --- a/src/hooks/useSpecialOfferConfig.ts +++ b/src/hooks/useSpecialOfferConfig.ts @@ -28,10 +28,16 @@ export const ALLOWED_PATHS = [ 'heisect', 'bjoern', 'lefiltre', + 'ultimate', + 'annual', ]; export const ALTERNATE_RECOMENDATED_PLAN_PATHS = new Set([]); export const DARK_MODE_PATHS = new Set(['baity', 'xavier', 'oscar', 'rimembah', 'believemy', 'ghareeb']); export const ALTERNATIVE_IMAGES_PATHS = new Set(['baity']); +export const ONLY_ULTIMATE_PLANS_PATHS = new Set(['ultimate']); +export const ULTIMATE_PREMIUM_PLANS_PATHS = new Set(['annual']); +export const ANNUAL_PLANS_PATHS = new Set(['annual', 'ultimate']); + export const COUPON_CODES = { baity: PromoCodeName.BaityBait, xavier: PromoCodeName.Xavier, @@ -58,6 +64,8 @@ export const COUPON_CODES = { heisect: PromoCodeName.heisect, bjoern: PromoCodeName.bjoern, lefiltre: PromoCodeName.lefiltre, + ultimate: PromoCodeName.cloudoff, + annual: PromoCodeName.cloudoff, }; interface OfferConfig { @@ -66,6 +74,9 @@ interface OfferConfig { alternateRecommendedPlan: boolean; couponCode: PromoCodeName | undefined; alternativeImages: string | null; + onlyUltimatePlan: boolean; + ultimateAndPremiumPlans: boolean; + annualPlans: boolean; } export const useOfferConfig = (pathname: string): OfferConfig => { @@ -79,12 +90,18 @@ export const useOfferConfig = (pathname: string): OfferConfig => { alternateRecommendedPlan: false, couponCode: undefined, alternativeImages: null, + onlyUltimatePlan: false, + ultimateAndPremiumPlans: false, + annualPlans: false, }; } const isDarkMode = DARK_MODE_PATHS.has(selectedPathname); const alternateRecommendedPlan = !ALTERNATE_RECOMENDATED_PLAN_PATHS.has(selectedPathname); const couponCode = COUPON_CODES[selectedPathname as keyof typeof COUPON_CODES]; + const onlyUltimatePlan = ONLY_ULTIMATE_PLANS_PATHS.has(selectedPathname); + const ultimateAndPremiumPlans = ULTIMATE_PREMIUM_PLANS_PATHS.has(selectedPathname); + const annualPlans = ANNUAL_PLANS_PATHS.has(selectedPathname); const alternativeImages = ALTERNATIVE_IMAGES_PATHS.has(selectedPathname) ? selectedPathname @@ -96,6 +113,9 @@ export const useOfferConfig = (pathname: string): OfferConfig => { alternateRecommendedPlan, couponCode, alternativeImages, + onlyUltimatePlan, + ultimateAndPremiumPlans, + annualPlans, }; }, [pathname]); }; diff --git a/src/lib/types/index.ts b/src/lib/types/index.ts index abe6ec7f2..f0de32223 100644 --- a/src/lib/types/index.ts +++ b/src/lib/types/index.ts @@ -208,6 +208,7 @@ export enum PromoCodeName { devopstoolbox = 'DEVOPSTOOLBOX', bjoern = 'BJOERN', lefiltre = 'LEFILTRE', + cloudoff = 'CLOUDOFF', } export interface PromoCodeProps { diff --git a/src/pages/[filename].tsx b/src/pages/[filename].tsx index d4f6cb2bc..e31187e6d 100644 --- a/src/pages/[filename].tsx +++ b/src/pages/[filename].tsx @@ -10,7 +10,7 @@ import TrustedSection from '@/components/home/TrustedSection'; import HorizontalScrollableSection from '@/components/home/HorizontalScrollableSection'; import FloatingCtaSectionv2 from '@/components/shared/FloatingCtaSectionV2'; import { PricingSectionWrapper } from '@/components/shared/pricing/PricingSectionWrapper'; -import { stripeService } from '@/services/stripe.service'; +import { Interval, stripeService } from '@/services/stripe.service'; import { SpecialOfferText } from '@/assets/types/specialOfferTemplate'; import { useOfferConfig, usePathRedirect } from '@/hooks/useSpecialOfferConfig'; import FeaturesSection from '@/components/drive/FeaturesSection'; @@ -74,6 +74,8 @@ const LANG_MAP = { devopstoolbox: 'en', bjoern: 'de', lefiltre: 'fr', + annual: 'en', + ultimate: 'en', }; function CombinedSpecialOffer({ @@ -84,8 +86,16 @@ function CombinedSpecialOffer({ navbarLang, pathname, }: CombinedSpecialOfferProps): JSX.Element { - const { selectedPathname, isDarkMode, alternateRecommendedPlan, couponCode, alternativeImages } = - useOfferConfig(pathname); + const { + selectedPathname, + isDarkMode, + alternateRecommendedPlan, + couponCode, + alternativeImages, + onlyUltimatePlan, + ultimateAndPremiumPlans, + annualPlans, + } = useOfferConfig(pathname); const { products, loadingCards, @@ -109,7 +119,7 @@ function CombinedSpecialOffer({ const decimalDiscountForLifetime = lifetimeCoupon?.percentOff && 100 - lifetimeCoupon.percentOff; const percentOff = individualCoupon?.percentOff !== undefined ? String(individualCoupon.percentOff) : '0'; const themeClasses = getThemeClasses(isDarkMode); - + const openerInterval = annualPlans ? Interval.Year : Interval.Lifetime; const parsePercentText = (text: string) => { if (!individualCoupon?.percentOff) { return
; @@ -147,7 +157,7 @@ function CombinedSpecialOffer({ return ( - + Date: Thu, 12 Feb 2026 15:27:31 +0100 Subject: [PATCH 3/3] Update next.config.js --- next.config.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/next.config.js b/next.config.js index 09bf62087..27ceae63f 100644 --- a/next.config.js +++ b/next.config.js @@ -257,6 +257,11 @@ module.exports = { destination: '/:path*', permanent: true, }, + { + source: '/webdav', + destination: '/webdav-rclone', + permanent: true, + }, ]; }, images: {