Skip to content

Commit 8e98ff4

Browse files
authored
Feat/layout UI changes (#67)
* add updated styles for vpn purchase area Signed-off-by: JaeBrian <[email protected]> * darker overlay, column vpn instances, and mobile logic Signed-off-by: JaeBrian <[email protected]> * sort vpn instances, and remove trash icon Signed-off-by: JaeBrian <[email protected]> * remove import and prop Signed-off-by: JaeBrian <[email protected]> * add first time visitor tooltips, added random information text for now Signed-off-by: JaeBrian <[email protected]> * fix to pass correct prop Signed-off-by: JaeBrian <[email protected]> * vpn selections hidden behind tooltip bug Signed-off-by: JaeBrian <[email protected]> * button is a little too chunky Signed-off-by: JaeBrian <[email protected]> --------- Signed-off-by: JaeBrian <[email protected]>
1 parent 779d67b commit 8e98ff4

File tree

10 files changed

+409
-203
lines changed

10 files changed

+409
-203
lines changed

package-lock.json

Lines changed: 46 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"react-dom": "^19.1.1",
2323
"react-hot-toast": "^2.6.0",
2424
"react-router": "^7.8.2",
25+
"react-tooltip": "^5.29.1",
2526
"tailwindcss": "^4.1.8",
2627
"vite-plugin-top-level-await": "^1.6.0",
2728
"zustand": "^5.0.8"

src/components/FloatingWalletButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const FloatingWalletButton = () => {
4747

4848
return (
4949
<>
50-
<LoadingOverlay isVisible={isLoading} message="Connecting Wallet..." />
50+
<LoadingOverlay isVisible={isLoading} messageTop="Connecting Wallet..." />
5151
<button
5252
onClick={handleConnect}
5353
disabled={isLoading}

src/components/LoadingOverlay.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,25 @@ import cardanoIcon from '/cardano-icon.svg'
22

33
interface LoadingOverlayProps {
44
isVisible: boolean
5-
message?: string
5+
messageTop?: string
6+
messageBottom?: string
67
}
78

8-
const LoadingOverlay = ({ isVisible, message }: LoadingOverlayProps) => {
9+
const LoadingOverlay = ({ isVisible, messageTop, messageBottom }: LoadingOverlayProps) => {
910
if (!isVisible) return null
1011

1112
return (
12-
<div className="fixed inset-0 bg-black/60 flex items-center justify-center z-[9999]">
13+
<div className="fixed inset-0 bg-black/80 flex items-center justify-center z-[9999]">
1314
<div className="flex flex-col items-center space-y-4">
1415
<div className="relative w-20 h-20 flex items-center justify-center">
1516
{/* Bigger White Cardano Icon */}
1617
<img src={cardanoIcon} alt="Cardano" className="w-16 h-16 animate-pulse brightness-0 invert" />
1718
</div>
18-
{message && (
19-
<div className="text-lg font-medium text-white">{message}</div>
19+
{messageTop && (
20+
<div className="text-lg font-medium text-white">{messageTop}</div>
21+
)}
22+
{messageBottom && (
23+
<div className="text-lg font-medium text-white">{messageBottom}</div>
2024
)}
2125
</div>
2226
</div>

src/components/Navigation.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,28 @@ import { useWalletStore } from '../stores/walletStore'
88
const Navigation = () => {
99
const location = useLocation()
1010
const isAccountPage = location.pathname === '/account'
11-
const { isWalletModalOpen, toggleWalletModal, reconnectWallet } = useWalletStore()
11+
const { isWalletModalOpen, toggleWalletModal, closeWalletModal, reconnectWallet } = useWalletStore()
1212

1313
useEffect(() => {
1414
reconnectWallet()
1515
}, [reconnectWallet])
1616

17+
useEffect(() => {
18+
const handleResize = () => {
19+
if (window.innerWidth >= 768 && isWalletModalOpen) {
20+
closeWalletModal()
21+
}
22+
}
23+
24+
window.addEventListener('resize', handleResize)
25+
26+
handleResize()
27+
28+
return () => {
29+
window.removeEventListener('resize', handleResize)
30+
}
31+
}, [isWalletModalOpen, closeWalletModal])
32+
1733
return (
1834
<nav className="absolute top-0 left-0 right-0 z-50 bg-[#00000033]">
1935
<div className="flex max-w-[80rem] justify-between items-center flex-1 self-stretch mx-auto p-4">
@@ -23,7 +39,7 @@ const Navigation = () => {
2339
{isAccountPage ? (
2440
<button
2541
onClick={toggleWalletModal}
26-
className={`flex items-center justify-center cursor-pointer transition-all duration-200 ${
42+
className={`md:hidden flex items-center justify-center cursor-pointer transition-all duration-200 ${
2743
isWalletModalOpen
2844
? 'w-12 h-12 rounded-full border-[1px] border-white'
2945
: 'w-12 h-12'

src/components/TooltipGuide.tsx

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { useState, useEffect, type ReactNode } from 'react'
2+
import { Tooltip } from 'react-tooltip'
3+
4+
export interface TooltipStep {
5+
id: string
6+
content: string
7+
placement?: 'top' | 'bottom' | 'left' | 'right'
8+
}
9+
10+
interface TooltipGuideProps {
11+
steps: TooltipStep[]
12+
storageKey: string
13+
stepDuration?: number
14+
onComplete?: () => void
15+
children: (showTooltips: boolean) => ReactNode
16+
}
17+
18+
const TooltipGuide = ({
19+
steps,
20+
storageKey,
21+
onComplete,
22+
children
23+
}: TooltipGuideProps) => {
24+
const [showTooltips, setShowTooltips] = useState<boolean>(false)
25+
const [currentStep, setCurrentStep] = useState<number>(0)
26+
27+
useEffect(() => {
28+
const hasVisited = localStorage.getItem(storageKey)
29+
if (!hasVisited) {
30+
setTimeout(() => {
31+
setShowTooltips(true)
32+
}, 500)
33+
localStorage.setItem(storageKey, 'true')
34+
}
35+
}, [storageKey])
36+
37+
const handleNextStep = () => {
38+
if (currentStep < steps.length - 1) {
39+
setCurrentStep(prev => prev + 1)
40+
} else {
41+
setShowTooltips(false)
42+
onComplete?.()
43+
}
44+
}
45+
46+
const renderTooltipContent = (content: string) => {
47+
return (
48+
<div className="flex flex-col gap-3">
49+
<div className="text-base leading-relaxed">
50+
{content}
51+
</div>
52+
<div className="flex justify-end">
53+
<button
54+
onClick={handleNextStep}
55+
className="bg-white/20 hover:bg-white/30 text-white px-3 py-1.5 rounded-md text-sm transition-all duration-200 font-medium cursor-pointer"
56+
>
57+
{currentStep < steps.length - 1 ? 'Next' : 'Got it!'}
58+
</button>
59+
</div>
60+
</div>
61+
)
62+
}
63+
64+
return (
65+
<>
66+
{children(showTooltips)}
67+
{showTooltips && steps.map((step, index) => (
68+
<Tooltip
69+
key={step.id}
70+
id={step.id}
71+
place={step.placement || 'top'}
72+
isOpen={showTooltips && currentStep === index}
73+
clickable={true}
74+
style={{
75+
backgroundColor: '#9400FF',
76+
color: 'white',
77+
borderRadius: '12px',
78+
padding: '16px',
79+
fontSize: '20px',
80+
maxWidth: '350px',
81+
zIndex: showTooltips && currentStep === index ? 10000 : 9999,
82+
boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.25), 0 8px 10px -6px rgba(0, 0, 0, 0.1)'
83+
}}
84+
>
85+
{renderTooltipContent(step.content)}
86+
</Tooltip>
87+
))}
88+
</>
89+
)
90+
}
91+
92+
export default TooltipGuide

src/components/VpnInstance.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import trashIcon from '/trash-icon.svg'
2-
31
interface VpnInstanceProps {
42
region: string
53
duration: string
@@ -9,7 +7,7 @@ interface VpnInstanceProps {
97
onAction?: () => void
108
}
119

12-
const VpnInstance = ({ region, duration, status, expires, onDelete, onAction }: VpnInstanceProps) => {
10+
const VpnInstance = ({ region, duration, status, expires, onAction }: VpnInstanceProps) => {
1311
return (
1412
<div className={`flex p-4 flex-col justify-center items-start gap-3 w-full rounded-md backdrop-blur-xs ${
1513
status === "Active"
@@ -29,13 +27,7 @@ const VpnInstance = ({ region, duration, status, expires, onDelete, onAction }:
2927
<p className="text-sm md:text-base">Expires: {expires}</p>
3028
</div>
3129
</div>
32-
<div className="flex justify-between items-center w-full">
33-
<img
34-
className="w-5 h-5 cursor-pointer"
35-
src={trashIcon}
36-
alt="trash icon"
37-
onClick={onDelete}
38-
/>
30+
<div className="flex justify-end items-center w-full">
3931
<button
4032
className="flex items-center justify-center gap-3 rounded-md py-1.5 px-3.5 backdrop-blur-xs box-shadow-sm cursor-pointer bg-white text-black"
4133
onClick={onAction}

src/components/WalletModal.tsx

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ interface WalletModalProps {
66
}
77

88
const WalletModal = ({ isOpen, onDisconnect }: WalletModalProps) => {
9-
const { balance, enabledWallet, walletAddress, isConnected, connect } = useWalletStore()
9+
const { enabledWallet, walletAddress, isConnected, connect } = useWalletStore()
1010

1111
if (!isOpen) return null
1212

@@ -32,29 +32,26 @@ const WalletModal = ({ isOpen, onDisconnect }: WalletModalProps) => {
3232
}
3333

3434
return (
35-
<div className="w-full bg-transparent flex justify-end">
36-
<div className="min-w-full sm:min-w-[37.8125rem] px-4 py-8">
35+
<div className="w-full bg-transparent flex justify-center">
36+
<div className="min-w-full py-10">
3737
<div className="border-1 border-white rounded-md bg-transparent p-6">
3838
{!isConnected ? (
3939
// Wallet not connected - show connection prompt
4040
<div className="flex flex-col items-start gap-2">
4141
<div className="flex items-center gap-3">
4242
<img
43-
src="/wallet-icon-white.svg"
44-
alt="Wallet"
45-
className="w-8 h-8"
43+
src="/cardano-icon.svg"
44+
alt="cardano-icon"
45+
className="w-10 h-10 brightness-0 invert"
4646
/>
4747
<div className="flex flex-col">
4848
<h3 className="text-white font-medium text-lg">Connect Wallet</h3>
49-
<p className="text-white/70 text-sm">Connect your wallet to purchase VPN access</p>
49+
<p className="text-white/70 text-md py-2">Connect your wallet to purchase VPN access</p>
5050
</div>
5151
</div>
52-
<div className="text-center">
53-
<p className="text-white text-lg font-bold">0.00 <span className="text-sm font-normal">ADA</span></p>
54-
</div>
5552
<button
5653
onClick={handleConnect}
57-
className="bg-white text-black px-6 py-2 rounded-lg font-medium w-fit"
54+
className="bg-white text-black px-6 py-2 rounded-lg font-medium w-fit cursor-pointer hover:bg-[#f5f5f5] hover:scale-102"
5855
>
5956
Connect Wallet
6057
</button>
@@ -66,30 +63,22 @@ const WalletModal = ({ isOpen, onDisconnect }: WalletModalProps) => {
6663
<div className="flex flex-col gap-4">
6764
<div className="flex items-center gap-3">
6865
<img
69-
src="/wallet-icon-white.svg"
66+
src="/cardano-icon.svg"
7067
alt="Wallet"
71-
className="w-8 h-8"
68+
className="w-10 h-10 brightness-0 invert"
7269
/>
7370
<div className="flex flex-col">
7471
<h3 className="text-white font-medium text-lg">Your Wallet</h3>
75-
<p className="text-white/70 text-sm max-w-[10rem] truncate">{enabledWallet}: {walletAddress}</p>
72+
<p className="text-white/70 text-md max-w-[15rem] py-1 truncate">{enabledWallet}: {walletAddress}</p>
7673
</div>
7774
</div>
7875
<button
7976
onClick={onDisconnect}
80-
className="bg-white text-black px-6 py-2 rounded-lg font-medium w-fit self-start"
77+
className="bg-white text-black px-6 py-2 rounded-lg font-medium w-fit self-start cursor-pointer hover:bg-[#f5f5f5] hover:scale-102"
8178
>
8279
Disconnect
8380
</button>
8481
</div>
85-
86-
{/* Right side */}
87-
<div className="text-right">
88-
<p className="text-white/70 text-sm mb-2 font-normal">Wallet Balance</p>
89-
<p className="text-white text-2xl font-bold">
90-
{balance || "0.00"} <span className="text-sm font-normal">ADA</span>
91-
</p>
92-
</div>
9382
</div>
9483
)}
9584
</div>

src/main.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { createRoot } from 'react-dom/client'
33
import { BrowserRouter } from 'react-router'
44
import './index.css'
55
import VpnApp from './App.tsx'
6+
import 'react-tooltip/dist/react-tooltip.css'
67

78
createRoot(document.getElementById('root')!).render(
89
<StrictMode>

0 commit comments

Comments
 (0)