Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wallets Page #23

Merged
merged 1 commit into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading