The weeb for the next gen discord boat - Wamellow wamellow.com
bot discord
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

add modal premium upsell banner

Luna 42980681 10c47c08

+61 -5
+2 -2
app/(home)/premium/checkout/api.ts
··· 4 4 url: string; 5 5 } 6 6 7 - export async function createCheckout(session: string, donationQuantity: number) { 7 + export async function createCheckout(session: string, donationQuantity: number, referer: string) { 8 8 const response = await fetch(`${process.env.NEXT_PUBLIC_API}/users/@me/billing/checkout`, { 9 9 method: "PUT", 10 10 headers: { 11 11 "Content-Type": "application/json", 12 12 Cookie: `session=${session}` 13 13 }, 14 - body: JSON.stringify({ donationQuantity }) 14 + body: JSON.stringify({ donationQuantity, referer }) 15 15 }); 16 16 17 17 const res = await response.json() as CheckoutResponse | ApiError;
+3 -1
app/(home)/premium/checkout/route.ts
··· 15 15 } 16 16 17 17 const donationQuantity = parseInt(searchParams.get("donation") || "0"); 18 - const url = await createCheckout(session.value, donationQuantity) 18 + const referer = request.headers.get("referer") || ""; 19 + 20 + const url = await createCheckout(session.value, donationQuantity, referer) 19 21 .catch((e) => e); 20 22 21 23 if (url instanceof Error) {
+56 -2
components/modal.tsx
··· 1 1 "use client"; 2 2 3 + import Link from "next/link"; 3 4 import { useEffect, useState } from "react"; 5 + import { HiFire } from "react-icons/hi"; 4 6 5 7 import type { ApiError } from "@/typings"; 6 8 import { cn } from "@/utils/cn"; 7 9 8 10 import Notice, { NoticeType } from "./notice"; 11 + import { Badge } from "./ui/badge"; 9 12 import { Button } from "./ui/button"; 10 13 import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "./ui/dialog"; 11 14 import { Separator } from "./ui/separator"; ··· 102 105 103 106 <div 104 107 className={cn( 105 - "scrollbar-hide overflow-y-scroll overflow-x-hidden max-h-[70vh] py-2", 108 + "scrollbar-hide overflow-y-scroll overflow-x-hidden max-h-[70vh] py-2 px-0.5", 106 109 className 107 110 )} 108 111 > 109 112 {error && ( 110 - <Notice 113 + <ModalNotice 111 114 type={NoticeType.Error} 112 115 message={error} 113 116 /> ··· 141 144 </DialogFooter> 142 145 </DialogContent> 143 146 </Dialog> 147 + ); 148 + } 149 + 150 + function ModalNotice({ 151 + icon, 152 + message, 153 + type = NoticeType.Info, 154 + location = "side", 155 + children 156 + }: Parameters<typeof Notice>[0]) { 157 + if (message.toLowerCase().includes("premium")) { 158 + return ( 159 + <div className="relative"> 160 + <Notice 161 + icon={<HiFire className="size-4" />} 162 + message={message} 163 + type={NoticeType.Info} 164 + location="bottom" 165 + > 166 + <Button 167 + asChild 168 + className="mt-2" 169 + size="sm" 170 + > 171 + <Link 172 + href={`/premium?utm_source=${window.location.hostname}&utm_medium=modal`} 173 + target="_blank" 174 + > 175 + Upgrade 176 + </Link> 177 + </Button> 178 + </Notice> 179 + 180 + <div className="absolute -top-2 -right-0.5 z-10"> 181 + <Badge className="rotate-3 backdrop-blur-md backdrop-brightness-75"> 182 + First Month Free!! 183 + </Badge> 184 + </div> 185 + </div> 186 + ); 187 + } 188 + 189 + return ( 190 + <Notice 191 + icon={icon} 192 + message={message} 193 + type={type} 194 + location={location} 195 + > 196 + {children} 197 + </Notice> 144 198 ); 145 199 }