@@ -22,7 +22,7 @@ const generateChecksum = (lastShown: string | null, nextShowTime: string): strin
2222 let hash = 0
2323 for ( let i = 0 ; i < data . length ; i ++ ) {
2424 const char = data . charCodeAt ( i )
25- hash = ( ( hash << 5 ) - hash ) + char
25+ hash = ( hash << 5 ) - hash + char
2626 hash = hash & hash // Convert to 32-bit integer
2727 }
2828 return Math . abs ( hash ) . toString ( 36 )
@@ -58,7 +58,7 @@ const validateData = (data: DonationData): boolean => {
5858 }
5959
6060 // Validate: nextShowTime shouldn't be more than 4 days after lastShown (max 3 days + 1 day buffer)
61- const maxExpectedNext = lastShownTimestamp + ( 4 * 24 * 60 * 60 * 1000 )
61+ const maxExpectedNext = lastShownTimestamp + 4 * 24 * 60 * 60 * 1000
6262 if ( nextShowTimestamp > maxExpectedNext ) {
6363 console . warn ( 'Donation popup: nextShowTime too far in future' )
6464 return false
@@ -67,9 +67,9 @@ const validateData = (data: DonationData): boolean => {
6767
6868 // Validate: nextShowTime shouldn't be more than 1 year in the past or future from now
6969 const now = Date . now ( )
70- const oneYearAgo = now - ( 365 * 24 * 60 * 60 * 1000 )
71- const oneYearLater = now + ( 365 * 24 * 60 * 60 * 1000 )
72-
70+ const oneYearAgo = now - 365 * 24 * 60 * 60 * 1000
71+ const oneYearLater = now + 365 * 24 * 60 * 60 * 1000
72+
7373 if ( nextShowTimestamp < oneYearAgo || nextShowTimestamp > oneYearLater ) {
7474 console . warn ( 'Donation popup: nextShowTime outside reasonable range' )
7575 return false
@@ -111,7 +111,7 @@ export default function DonationPopup() {
111111 const checkShouldShow = ( ) => {
112112 const data = getStorageData ( )
113113 const now = Date . now ( )
114-
114+
115115 if ( ! data ) {
116116 // First time - schedule for 1 hour from now and store it
117117 const nextShowTime = new Date ( now + FIRST_SHOW_DELAY ) . toISOString ( )
@@ -139,15 +139,15 @@ export default function DonationPopup() {
139139 const showPopup = ( ) => {
140140 const now = Date . now ( )
141141 // Update storage: set lastShown to now and nextShowTime to 3 days from now
142- const nextShowTime = new Date ( now + ( DAYS_BETWEEN_SHOWS * 24 * 60 * 60 * 1000 ) ) . toISOString ( )
143- setStorageData ( {
144- lastShown : new Date ( now ) . toISOString ( ) ,
145- nextShowTime
142+ const nextShowTime = new Date ( now + DAYS_BETWEEN_SHOWS * 24 * 60 * 60 * 1000 ) . toISOString ( )
143+ setStorageData ( {
144+ lastShown : new Date ( now ) . toISOString ( ) ,
145+ nextShowTime,
146146 } )
147-
147+
148148 // Make visible immediately
149149 setIsVisible ( true )
150-
150+
151151 // Start animation after a frame for smooth CSS transition
152152 requestAnimationFrame ( ( ) => {
153153 requestAnimationFrame ( ( ) => {
@@ -174,63 +174,57 @@ export default function DonationPopup() {
174174 if ( ! isVisible ) return null
175175
176176 return (
177- < div className = "fixed inset-0 z-[100] flex items-center justify-center p-4 pointer-events-none " >
177+ < div className = "pointer-events-none fixed inset-0 z-[100] flex items-center justify-center p-4" >
178178 { /* Backdrop */ }
179179 < div
180180 className = { cn (
181- 'absolute inset-0 bg-black/40 backdrop-blur-sm pointer-events-auto ' ,
182- 'transition-opacity duration-700 ease-in-out will-change-opacity ' ,
183- isAnimating ? 'opacity-100' : 'opacity-0'
181+ 'pointer-events-auto absolute inset-0 bg-black/40 backdrop-blur-sm' ,
182+ 'will-change-opacity transition-opacity duration-700 ease-in-out' ,
183+ isAnimating ? 'opacity-100' : 'opacity-0' ,
184184 ) }
185185 onClick = { handleClose }
186186 />
187187
188188 { /* Popup */ }
189189 < div
190190 className = { cn (
191- 'relative w-full max-w-md pointer-events-auto ' ,
191+ 'pointer-events-auto relative w-full max-w-md' ,
192192 'transform transition-all duration-700 ease-out will-change-transform' ,
193- isAnimating
194- ? 'translate-y-0 opacity-100 scale-100'
195- : '-translate-y-8 opacity-0 scale-95'
193+ isAnimating ? 'translate-y-0 scale-100 opacity-100' : '-translate-y-8 scale-95 opacity-0' ,
196194 ) }
197195 >
198- < div className = "relative bg-gradient-to-br from-card via-card to-card/95 border-2 border-primary/20 rounded-2xl shadow-2xl overflow-hidden " >
196+ < div className = "relative overflow-hidden rounded-2xl border-2 border-primary/20 bg-gradient-to-br from-card via-card to-card/95 shadow-2xl" >
199197 { /* Animated gradient background */ }
200198 < div className = "absolute inset-0 bg-gradient-to-br from-primary/5 via-transparent to-primary/10" />
201199 < div className = "absolute inset-0 bg-gradient-to-tr from-primary/0 via-primary/5 to-primary/0" />
202-
200+
203201 { /* Close button */ }
204- < button
205- onClick = { handleClose }
206- className = "absolute top-4 right-4 z-10 p-2 rounded-full bg-background/80 hover:bg-background transition-all duration-200 hover:scale-110"
207- aria-label = "Close"
208- >
209- < X className = "w-4 h-4" />
202+ < button onClick = { handleClose } className = "absolute right-4 top-4 z-10 rounded-full bg-background/80 p-2 transition-all duration-200 hover:scale-110 hover:bg-background" aria-label = "Close" >
203+ < X className = "h-4 w-4" />
210204 </ button >
211205
212206 { /* Content */ }
213207 < div className = "relative p-8" >
214208 { /* Heart icon with enhanced animation */ }
215- < div className = "flex justify-center mb-6 " >
209+ < div className = "mb-6 flex justify-center" >
216210 < div className = "relative" >
217- < div className = "absolute inset-0 bg-primary/30 rounded-full blur-xl" />
218- < div className = "absolute -inset-2 bg-primary/20 rounded-full animate-ping " style = { { animationDuration : '2s' } } />
219- < div className = "relative bg-gradient-to-br from-primary/20 to-primary/10 p-4 rounded-full backdrop-blur-sm border border-primary/20 " >
220- < Heart className = "w -10 h -10 text -primary fill -primary" />
211+ < div className = "absolute inset-0 rounded-full bg-primary/30 blur-xl" />
212+ < div className = "absolute -inset-2 animate-ping rounded-full bg-primary/20 " style = { { animationDuration : '2s' } } />
213+ < div className = "relative rounded-full border border-primary/20 bg-gradient-to-br from-primary/20 to-primary/10 p-4 backdrop-blur-sm" >
214+ < Heart className = "h -10 w -10 fill -primary text -primary" />
221215 </ div >
222216 </ div >
223217 </ div >
224218
225219 { /* Title */ }
226- < h3 className = "text-2xl font-bold text-center mb-3 bg-gradient-to-r from-primary via-primary to-primary/80 bg-clip-text text-transparent" >
220+ < h3 className = "mb-3 bg-gradient-to-r from-primary via-primary to-primary/80 bg-clip-text text-center text-2xl font-bold text-transparent" >
227221 { t ( 'donation.title' , { defaultValue : 'Support PasarGuard' } ) }
228222 </ h3 >
229223
230224 { /* Message */ }
231- < p className = "text-sm text-muted-foreground text-center mb-6 leading-relaxed px-2 " >
232- { t ( 'donation.message' , {
233- defaultValue : 'Your support helps us improve PasarGuard and build better features for everyone!'
225+ < p className = "mb-6 px-2 text-center text-sm leading-relaxed text-muted-foreground " >
226+ { t ( 'donation.message' , {
227+ defaultValue : 'Your support helps us improve PasarGuard and build better features for everyone!' ,
234228 } ) }
235229 </ p >
236230
@@ -239,24 +233,19 @@ export default function DonationPopup() {
239233 < Button
240234 onClick = { handleDonate }
241235 size = "lg"
242- className = "w-full bg-gradient-to-r from-primary to-primary/90 hover:from-primary/90 hover:to-primary text-primary-foreground font-semibold shadow-lg hover:shadow-xl transition-all duration-300 hover:scale-[1.03] active:scale-[0.98]"
236+ className = "w-full bg-gradient-to-r from-primary to-primary/90 font-semibold text-primary-foreground shadow-lg transition-all duration-300 hover:scale-[1.03] hover:from-primary/90 hover:to-primary hover:shadow-xl active:scale-[0.98]"
243237 >
244- < Heart className = "w-5 h-5 mr-2 fill-current" />
238+ < Heart className = "mr-2 h-5 w-5 fill-current" />
245239 { t ( 'donation.donate' , { defaultValue : 'Donate Now' } ) }
246240 </ Button >
247241
248242 < Button
249243 onClick = { handleGitHub }
250244 variant = "outline"
251245 size = "lg"
252- className = "w-full border-primary/30 hover:bg-primary/5 hover:border-primary/50 transition-all duration-300 hover:scale-[1.03] active:scale-[0.98]"
246+ className = "w-full border-primary/30 transition-all duration-300 hover:scale-[1.03] hover:border-primary/50 hover:bg-primary/5 active:scale-[0.98]"
253247 >
254- < svg
255- className = "w-5 h-5 mr-2"
256- fill = "currentColor"
257- viewBox = "0 0 24 24"
258- xmlns = "http://www.w3.org/2000/svg"
259- >
248+ < svg className = "mr-2 h-5 w-5" fill = "currentColor" viewBox = "0 0 24 24" xmlns = "http://www.w3.org/2000/svg" >
260249 < path d = "M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
261250 </ svg >
262251 { t ( 'donation.starOnGitHub' , { defaultValue : 'Star on GitHub' } ) }
@@ -268,4 +257,3 @@ export default function DonationPopup() {
268257 </ div >
269258 )
270259}
271-
0 commit comments