Skip to content

Commit f656019

Browse files
committed
feat: passport info popup in home
1 parent 28dfcc0 commit f656019

File tree

8 files changed

+209
-13
lines changed

8 files changed

+209
-13
lines changed

public/assets/info.svg

Lines changed: 8 additions & 0 deletions
Loading

src/components/MiningStatus/index.css

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@
3434
}
3535

3636
.circle.red {
37-
background-color: #ff0000;
37+
background-color: #b3261e;
38+
}
39+
.circle.yellow {
40+
background-color: #f0b90b;
3841
}
3942

4043
.miners {
@@ -48,3 +51,14 @@
4851
align-items: center;
4952
gap: 4px;
5053
}
54+
55+
.passport-status {
56+
display: flex;
57+
flex-direction: row;
58+
align-items: center;
59+
gap: 4px;
60+
padding: 8px 14px;
61+
background-color: #282930;
62+
border-radius: 16px;
63+
cursor: pointer;
64+
}

src/components/MiningStatus/index.tsx

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,43 @@ import "./index.css";
33
import { useDaemonContext } from '../../providers/DaemonProvider';
44
import Skeleton from '../Skeleton';
55

6+
const OneDayInSeconds = 86400;
7+
68
const MiningStatus = () => {
7-
const { miningData } = useDaemonContext();
9+
const { miningData, profiles, setIsPassportInfoOpen } = useDaemonContext();
810
const [isMiningUp, setIsMiningUp] = useState<boolean>(false);
11+
const [passportTimeLeft, setPassportTimeLeft] = useState<number>(0);
912

1013
useEffect(() => {
1114
if (miningData) {
1215
setIsMiningUp(miningData?.status === 200)
1316
}
14-
1517
}, [miningData])
1618

19+
useEffect(() => {
20+
const passportExpiration = profiles?.[0]?.activeFreePassport?.expires
21+
if (passportExpiration) {
22+
const timeLeft = passportExpiration - Math.floor(Date.now() / 1000)
23+
setPassportTimeLeft(timeLeft)
24+
}
25+
}, [profiles])
26+
27+
const openPassportInfo = () => {
28+
setIsPassportInfoOpen(true)
29+
}
30+
1731
return (
1832
<div className="mining-status">
1933
<div className="miners">
20-
<div className={`circle ${isMiningUp ? "green" : "red"}`}></div>
2134
Miners: {miningData?.online ? miningData.online : <Skeleton height="14px" width="45px" />}
2235
</div>
2336

37+
<div className='passport-status' onClick={openPassportInfo}>
38+
<div className={`circle ${passportTimeLeft < OneDayInSeconds ? passportTimeLeft <= 0 ? "red" : "yellow" : "green"}`}></div>
39+
Freemium
40+
<img src="/assets/info.svg" alt="Info icon" />
41+
</div>
42+
2443
<div className="users">Users: {miningData?.totalUsers ? miningData.totalUsers : <Skeleton height="14px" width="45px" />}</div>
2544
</div>
2645
);
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
.home-popup-backdrop {
2+
position: fixed;
3+
top: 0;
4+
left: 0;
5+
width: 100%;
6+
height: 100%;
7+
background-color: rgba(0, 0, 0, 0.5);
8+
z-index: 10;
9+
width: 100%;
10+
height: 100%;
11+
display: flex;
12+
flex-direction: column;
13+
justify-content: center;
14+
align-items: center;
15+
padding: 0 16px;
16+
}
17+
18+
.home-nft-info {
19+
display: flex;
20+
flex-direction: column;
21+
gap: 40px;
22+
background: #191919;
23+
border-radius: 16px;
24+
padding: 16px;
25+
width: 100%;
26+
max-width: 380px;
27+
}
28+
29+
.home-main-card {
30+
display: flex;
31+
justify-content: space-between;
32+
align-items: center;
33+
}
34+
35+
.home-main-card span {
36+
font-size: 14px;
37+
color: #989899;
38+
}
39+
40+
.home-main-card p {
41+
font-size: 24px;
42+
}
43+
44+
.home-main-card div:last-child {
45+
text-align: right;
46+
}
47+
48+
.home-buttons {
49+
display: flex;
50+
gap: 8px;
51+
}
52+
53+
.home-buttons button {
54+
flex: 1;
55+
display: flex;
56+
justify-content: center;
57+
align-items: center;
58+
59+
padding: 16px 8px;
60+
border: 0;
61+
border-radius: 16px;
62+
font-weight: 700;
63+
64+
cursor: pointer;
65+
}
66+
67+
.home-buttons button:first-child {
68+
background-color: #9fbfe533;
69+
color: #9fbfe5fe;
70+
display: flex;
71+
align-items: center;
72+
justify-content: center;
73+
gap: 8px;
74+
}
75+
76+
.home-buttons button:last-child {
77+
background-color: #282930;
78+
color: #ffffff;
79+
}
80+
81+
.home-options {
82+
display: flex;
83+
flex-direction: column;
84+
gap: 26px;
85+
86+
margin-bottom: 36px;
87+
}
88+
89+
.option-group {
90+
text-align: left;
91+
}
92+
93+
.option-group h3 {
94+
margin-bottom: 8px;
95+
}
96+
97+
.home-disabled {
98+
background: #191919 !important;
99+
color: #5a5a5afe !important;
100+
}
101+
102+
.home-buttons button.home-disabled {
103+
border: 1px solid #5a5a5afe;
104+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { useDaemonContext } from "../../providers/DaemonProvider";
2+
import { getRemainingTime } from "../../utils/utils";
3+
import './index.css';
4+
import Skeleton from "../Skeleton";
5+
6+
const PassportInfoPopup = () => {
7+
const { profiles, isPassportInfoOpen, setIsPassportInfoOpen } = useDaemonContext();
8+
9+
return isPassportInfoOpen ? (
10+
<div className="home-popup-backdrop" onClick={() => setIsPassportInfoOpen(false)}>
11+
<div className="home-nft-info">
12+
<div className="home-main-card">
13+
<div style={{ display: "flex", flexDirection: 'column', textAlign: 'start', gap: '16px' }}>
14+
<span>Silent Pass Passport</span>
15+
<p>Freemium</p>
16+
</div>
17+
18+
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'end', gap: '16px' }}>
19+
<span>Expiration date</span>
20+
{
21+
profiles?.[0]?.activeFreePassport?.expires ?
22+
<p>{getRemainingTime(profiles?.[0]?.activeFreePassport?.expires)}</p>
23+
: <Skeleton width='50px' height='20px' />
24+
}
25+
</div>
26+
</div>
27+
28+
<div className="home-buttons">
29+
<button className="home-disabled">
30+
<img src="./assets/conet-outline-gray.svg" />
31+
<span>Upgrade</span>
32+
</button>
33+
34+
<button onClick={() => setIsPassportInfoOpen(false)}>Close</button>
35+
</div>
36+
</div>
37+
</div>
38+
) : <></>
39+
};
40+
41+
export default PassportInfoPopup;

src/pages/Home/index.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ import RegionSelector from '../../components/RegionSelector';
1313
import { useNavigate } from 'react-router-dom';
1414
import { formatMinutesToHHMM } from "../../utils/utils";
1515
import { startSilentPass, stopSilentPass } from "../../api";
16-
import PassportInfo from "../../components/PassportInfo";
17-
import { conetProvider } from "../../utils/constants";
16+
import PassportInfoPopup from "../../components/PassportInfoPopup";
1817

1918
interface RenderButtonProps {
2019
errorStartingSilentPass: boolean;
@@ -87,7 +86,7 @@ const RenderButton = ({ errorStartingSilentPass, handleTogglePower, isConnection
8786

8887

8988
const Home = () => {
90-
const { profiles, sRegion, setSRegion, setAllRegions, allRegions, setIsRandom, getAllNodes, closestRegion, _vpnTimeUsedInMin } = useDaemonContext();
89+
const { profiles, sRegion, setSRegion, setAllRegions, allRegions, setIsRandom, getAllNodes, closestRegion, _vpnTimeUsedInMin, isPassportInfoOpen } = useDaemonContext();
9190
const [power, setPower] = useState<boolean>(false);
9291
const [isInitialLoading, setIsInitialLoading] = useState<boolean>(true);
9392
const [isConnectionLoading, setIsConnectionLoading] = useState<boolean>(false)
@@ -279,8 +278,6 @@ const Home = () => {
279278

280279
<CopyProxyInfo />
281280

282-
{/* <PassportInfo /> */}
283-
284281
{!isConnectionLoading &&
285282
<RegionSelector
286283
title={allRegions?.[sRegion]?.country}
@@ -294,6 +291,8 @@ const Home = () => {
294291
</div>
295292

296293
<Footer />
294+
295+
<PassportInfoPopup />
297296
</>
298297
);
299298
};

src/providers/DaemonProvider.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ type DaemonContext = {
2424
serverPac: string
2525
setServerPac: (pac: string) => void
2626
_vpnTimeUsedInMin: React.MutableRefObject<number>
27+
isPassportInfoOpen: boolean
28+
setIsPassportInfoOpen: (val: boolean) => void
2729
};
2830

2931
type DaemonProps = {
@@ -53,7 +55,9 @@ const defaultContextValue: DaemonContext = {
5355
setServerPort: () => { },
5456
serverPac: "",
5557
setServerPac: () => { },
56-
_vpnTimeUsedInMin: { current: 0 }
58+
_vpnTimeUsedInMin: { current: 0 },
59+
isPassportInfoOpen: false,
60+
setIsPassportInfoOpen: () => { }
5761
};
5862

5963
const Daemon = createContext<DaemonContext>(defaultContextValue);
@@ -76,6 +80,7 @@ export function DaemonProvider({ children }: DaemonProps) {
7680
const [serverPort, setServerPort] = useState<string>(defaultContextValue.serverPort);
7781
const [serverPac, setServerPac] = useState<string>("");
7882
const _vpnTimeUsedInMin = useRef<number>(0);
83+
const [isPassportInfoOpen, setIsPassportInfoOpen] = useState<boolean>(true);
7984

8085
useEffect(() => {
8186
{
@@ -86,7 +91,7 @@ export function DaemonProvider({ children }: DaemonProps) {
8691

8792

8893
return (
89-
<Daemon.Provider value={{ sRegion, setSRegion, allRegions, setAllRegions, closestRegion, setClosestRegion, isRandom, setIsRandom, miningData, setMiningData, profiles, setProfiles, isMiningUp, setIsMiningUp, getAllNodes, setaAllNodes, serverIpAddress, setServerIpAddress, serverPort, setServerPort, serverPac, setServerPac, _vpnTimeUsedInMin }}>
94+
<Daemon.Provider value={{ sRegion, setSRegion, allRegions, setAllRegions, closestRegion, setClosestRegion, isRandom, setIsRandom, miningData, setMiningData, profiles, setProfiles, isMiningUp, setIsMiningUp, getAllNodes, setaAllNodes, serverIpAddress, setServerIpAddress, serverPort, setServerPort, serverPac, setServerPac, _vpnTimeUsedInMin, isPassportInfoOpen, setIsPassportInfoOpen }}>
9095
{children}
9196
</Daemon.Provider>
9297
);

src/services/mining.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,14 @@ const startMiningV2 = async (
274274
return;
275275
}
276276

277-
// console.log("_startMiningV2 success", _data);
278-
const response: nodeResponse = JSON.parse(_data);
277+
let response: any = {};
278+
279+
try {
280+
response = JSON.parse(_data);
281+
} catch (ex) {
282+
console.log(ex);
283+
return;
284+
}
279285

280286
if (first) {
281287
first = false;

0 commit comments

Comments
 (0)