Skip to content

Commit

Permalink
Wallets page
Browse files Browse the repository at this point in the history
  • Loading branch information
d-la authored Aug 22, 2024
1 parent bac46e0 commit c4d4237
Show file tree
Hide file tree
Showing 35 changed files with 1,347 additions and 0 deletions.
Binary file added assets/wallets/icons/backpack.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/binance.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/bitget.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/brave.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/capsule.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/circle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/crossmint.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/decaf.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/exodus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/fuse.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/helium.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/keystone.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/ledger.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/okx.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/phantom.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/privy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/robinhood.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/solflare.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/tiplink.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/trustwalletcore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/turnkey.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/walletconnect.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/icons/web3auth.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wallets/wallet-placeholder-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -1526,5 +1526,27 @@
"cards": {
"view-details-title": "View Details"
}
},
"wallets": {
"meta": {
"title": "Solana Wallets - A More Powerful, Programmable Way to Blockchain",
"description": "Solana wallets offer more than custody - they're the gateway to web3 apps and services. Create a custom solution or amplify your offerings with an existing Solana implementation."
},
"hero": {
"eyebrow": "Wallet Finder",
"headline": "Find a Wallet That Works for You",
"body": "Select the features you need to discover a wallet that meets your needs."
},
"filters": {
"all-wallets": "All wallets"
},
"grid": {
"title": "Solana Wallets",
"no-results": "No results found!",
"reset-filters": "Reset filters"
},
"card": {
"view-details": "View Details"
}
}
}
46 changes: 46 additions & 0 deletions src/components/wallets/WalletCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { useTranslation } from "next-i18next";
import Image from "next/image";
import styles from "./WalletCard.module.scss";

const WalletCard = ({ index, walletImage, name, body, websiteUrl }) => {
const { t } = useTranslation();

return (
<article data-index={index} className={styles["wallet"]}>
<Image
src={walletImage}
width={60}
height={60}
alt={name}
className={styles["wallet-card-icon"]}
></Image>
<h3 className={styles["wallet-card-title"]}>{name}</h3>
<p className={styles["wallet-card-body"]}>{body}</p>
<a
href={websiteUrl}
className={styles["wallet-card-view-details"]}
target="_blank"
>
{t("wallets.card.view-details")}
<span>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-[15px] h-[15px] size-6"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3"
/>
</svg>
</span>
</a>
</article>
);
};

export default WalletCard;
64 changes: 64 additions & 0 deletions src/components/wallets/WalletCard.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
.wallet {
display: flex;
flex-flow: column wrap;
background-color: #1d1a23;
border-radius: 16px;
padding: 30px;
gap: 15px;
transition: all 0.3s ease;

&:hover {
transform: scale(1.05);
background-color: #2b2634;
}
}

.wallet-card-icon {
width: 60px;
height: auto;
}

.wallet-card-title {
font-size: 28px;
line-height: 33px;
font-family: "Diatype", var(--font-family-sans-serif);
margin-bottom: 0;
}

.wallet-card-body {
font-size: 16px;
font-family: "Diatype", var(--font-family-sans-serif);
line-height: 20px;
color: #6c6a81;
margin-bottom: 0;
}

.wallet-card-body--alt {
font-size: 16px;
font-family: "Diatype", var(--font-family-sans-serif);
line-height: 20px;
margin-bottom: 0;
color: #fff;
}

.wallet-card-view-details {
font-size: 14px;
font-family: "Diatype", monotype;
line-height: 20px;
letter-spacing: 0.5px;
text-transform: uppercase;
text-align: left;
margin-bottom: 0;
color: #fff;

span {
color: #9945ff;
font-size: 20px;

svg {
margin-left: 5px;
width: 20px;
height: 20px;
}
}
}
139 changes: 139 additions & 0 deletions src/components/wallets/WalletFilters.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { useTranslation } from "next-i18next";
import { useState } from "react";
import styles from "./WalletFilters.module.scss";
import Wallets from "./Wallets";

const WalletFilters = ({
filterData,
currentFilters,
setFilters,
updateWallets,
walletData,
}) => {
const { t } = useTranslation();

/**
* Returns all filter data with an extra key named `checked` set to false as the initial state of a filter
* @returns Object
*/
const setFilterInitialState = () => {
return filterData.map((filter) => ({ ...filter, checked: false }));
};

const [filterState, setFilterState] = useState(setFilterInitialState());

// Accepts the index of the filter and changes its checked state,
// then updates filterState to use the updated state
const toggleFilterActiveState = (index) => {
const filters = [...filterState];
filters[index].checked = !filters[index].checked;

setFilterState(filters);

const activeFilters = { ...currentFilters };
const filterKey = filters[index].filterKey;

// Add the filter as true to the filters state or remove the filter if its been unchecked
if (filters[index].checked) {
if (!(filterKey in activeFilters)) {
activeFilters[filterKey] = true;
}
} else {
if (filterKey in activeFilters) {
delete activeFilters[filterKey];
}
}

const showAllButton = document.querySelector(
'button[data-role="show-all"]',
);

setFilters(activeFilters);

// Handle case where a user checks a filter and then unchecks that same filter. If we have no filters active,
// show all wallets and set the "All wallets" button as active. If we have filters at least one filter active,
// remove active state from "All wallets" and show filtered wallets
if (Object.keys(activeFilters).length > 0) {
if (
showAllButton &&
showAllButton.classList.contains(`${styles["wallet-filter--active"]}`)
) {
showAllButton.classList.remove(`${styles["wallet-filter--active"]}`);
}

// Filters are active - show filtered results
updateWallets(activeFilters);
} else {
if (
showAllButton &&
!showAllButton.classList.contains(`${styles["wallet-filter--active"]}`)
) {
showAllButton.classList.add(`${styles["wallet-filter--active"]}`);
}

// No filters are active - show all
updateWallets({});
}
};

const resetWalletsAndFilters = () => {
setFilterState(setFilterInitialState()); // Reset all filters to unchecked
setFilters({}); // Remove all current filters
updateWallets({}); // Pass empty filters object to show all wallets

const showAllButton = document.querySelector(
'button[data-role="show-all"]',
);

if (
showAllButton &&
!showAllButton.classList.contains(`${styles["wallet-filter--active"]}`)
) {
showAllButton.classList.add(`${styles["wallet-filter--active"]}`);
}
};

return (
<>
<section className={styles["wallet-filter-section"]}>
<div>
<button
onClick={() => {
resetWalletsAndFilters();
}}
className={`${styles["wallet-filter"]} ${styles["wallet-filter--active"]}`}
data-role="show-all"
>
{t("wallets.filters.all-wallets")}
</button>
</div>
{filterState.length &&
filterState.map((filter, index) => (
<div key={index}>
<label
className={`${styles["wallet-filter"]} ${filter.checked ? styles["wallet-filter--active"] : ""}`}
htmlFor={filter.filterKey}
>
{filter.title}
</label>
<input
className={styles["wallet-filter-input"]}
type="checkbox"
name="filters"
id={filter.filterKey}
value={filter.filterKey}
checked={filter.checked}
onChange={() => toggleFilterActiveState(index)}
></input>
</div>
))}
</section>
<Wallets
walletData={walletData}
resetWalletsAndFilters={resetWalletsAndFilters}
/>
</>
);
};

export default WalletFilters;
51 changes: 51 additions & 0 deletions src/components/wallets/WalletFilters.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
.wallet-filter-section {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: center;
gap: 5px;
max-width: 1280px;
margin: 0 auto;
padding: 0 20px;
position: relative;
z-index: 10;
}

.wallet-filter {
display: inline-block;
background-color: #504d61;
color: #fff;
transition: all 0.3s ease;
border-radius: 30px;
padding: 7px 12px;
font-size: 12px;
text-transform: uppercase;
min-width: 50px;
text-align: center;
font-family: "Diatype", monotype;
line-height: 13px;
border: 1px solid #504d61;

&:hover {
background-color: #1d1a23;
cursor: pointer;
}
}

.wallet-filter--active {
background-color: #1d1a23;
color: #fff;
}

.wallet-filter + .wallet-filter-input:checked {
background-color: #1d1a23;
}

.wallet-filter.active {
background-color: #1d1a23;
color: #fff;
}

.wallet-filter-input {
appearance: none;
}
47 changes: 47 additions & 0 deletions src/components/wallets/Wallets.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useTranslation } from "next-i18next";
import styles from "./Wallets.module.scss";
import Button from "../shared/Button";
import WalletCard from "./WalletCard";

const Wallets = ({ walletData, resetWalletsAndFilters }) => {
const { t } = useTranslation();

return (
<>
<section className={styles["wallets-section"]}>
<h2 className={styles["wallets-title"]}>{t("wallets.grid.title")}</h2>
<div className={styles["wallets-grid"]}>
{walletData.length ? (
walletData.map((wallet, key) => {
return (
<WalletCard
index={key}
name={wallet.name}
walletImage={wallet.icon.src}
body={wallet.body}
websiteUrl={wallet.website}
key={key}
/>
);
})
) : (
<div className={styles["wallets-no-results-container"]}>
<p className={styles["wallets-no-results-found"]}>
{t("wallets.grid.no-results")}
</p>
<Button
variant="outline"
onClick={resetWalletsAndFilters}
className="ms-2"
>
{t("wallets.grid.reset-filters")}
</Button>
</div>
)}
</div>
</section>
</>
);
};

export default Wallets;
Loading

0 comments on commit c4d4237

Please sign in to comment.