Skip to content
Open
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
41 changes: 40 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import TermsOfUse from "./routes/terms-of-use";
import { AppProvider } from "./context/AppProvider";
import { client } from "./utils/web3/wagmi";
import { WagmiConfig } from "wagmi";
import { useEffect } from "react";
import { useEffect, useState } from "react";
import { ConnectWSCProvider } from "milkomeda-wsc-ui-test-beta";
import KYAModal from "./components/organisms/Modals/KYAModal";

const wscCustomTheme = {
"--wsc-body-background": "#100901",
Expand Down Expand Up @@ -41,7 +42,12 @@ const wscCustomTheme = {
"--wsc-connectbutton-active-background": "#2c2f3e",
"--wsc-connectbutton-active-color": "white"
};

const KYA_ACCEPTED_KEY = "kya_accepted";

export default function App() {
const [showKYAModal, setShowKYAModal] = useState(false);

useEffect(() => {
document.title = `Djed on ${process.env.REACT_APP_BC}`;

Expand All @@ -57,13 +63,46 @@ export default function App() {
// Update color
const color = getComputedStyle(root).getPropertyValue(`--${colorTheme}`);
root.style.setProperty("--gold-dark", color);

// Check if user has already accepted KYA
try {
const kyaAccepted = localStorage.getItem(KYA_ACCEPTED_KEY);
if (!kyaAccepted) {
setShowKYAModal(true);
}
} catch (error) {
// localStorage might be unavailable (private browsing, disabled)
console.warn('Unable to check KYA acceptance status:', error);
setShowKYAModal(true);
}
}, []);

const handleKYAAccept = () => {
try {
localStorage.setItem(KYA_ACCEPTED_KEY, "true");
} catch (error) {
console.warn('Unable to save KYA acceptance:', error);
// User accepted but we can't persist it - they'll see modal again next visit
}
setShowKYAModal(false);
};

const handleKYAClose = () => {
// Allow closing but don't save acceptance
// Modal will show again on next visit
setShowKYAModal(false);
};

return (
<BrowserRouter>
<WagmiConfig client={client}>
<AppProvider>
<ConnectWSCProvider customTheme={wscCustomTheme}>
<KYAModal
visible={showKYAModal}
onClose={handleKYAClose}
onAccept={handleKYAAccept}
/>
<Routes>
<Route path="/" element={<MainLayout />}>
<Route path="" element={<Protocol />} />
Expand Down
19 changes: 18 additions & 1 deletion src/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ iframe {
.ant-layout {
background: var(--gradient-theme-5);
padding-top: 2em;
height: 100vh;
min-height: 100vh;
overflow-y: auto;
display: flex;
flex-direction: column;
}

.ant-layout-content {
padding: 0 3em;
flex: 1;
}

.ant-layout-header {
Expand All @@ -50,6 +53,7 @@ iframe {
display: flex;
}
}

.header-mobile {
display: none;
}
Expand Down Expand Up @@ -86,6 +90,7 @@ iframe {
.ant-layout-header .ant-menu-item-disabled a {
color: $grey-5 !important;
}

.ant-dropdown-menu-item-disabled a {
color: $grey-5 !important;
}
Expand Down Expand Up @@ -219,11 +224,13 @@ iframe {
.ant-popover-arrow-content::before {
background: $black-2;
}

.ant-popover-inner-content {
background: $black-2;
display: flex;
flex-direction: column;
gap: 8px;

button.CustomButton {
width: 100%;
justify-content: start;
Expand All @@ -234,6 +241,7 @@ iframe {
}

@media only screen and (max-width: 425px) {

.ant-layout-header,
.ant-layout-content {
padding: 0 2em;
Expand All @@ -246,31 +254,38 @@ iframe {
padding: 0 2em;
color: white;
}

.menu-mobile-dropdown {
width: 300px;
background: rgba(0, 0, 0, 0.9);
top: 70px !important;
overflow: hidden;

.ant-dropdown-menu {
padding-top: 20px;
background: var(--gradient-theme-5);
border: 1px solid #5f606e;

.ant-dropdown-menu-item {
color: $white;
padding: 20px 2em;
text-align: center;

&:hover {
background: #2f3037;
}
}

button {
margin: 2em auto;
}

.menu-mobile-icon {
font-size: 40px;
}
}
}

.ant-layout-header {
flex-wrap: wrap;
height: auto;
Expand All @@ -287,13 +302,15 @@ iframe {
&.header-desktop {
display: none;
}

.WalletConfig {
margin-top: 1.5em;
justify-content: center;
width: 100%;
}
}
}

.ant-message {
z-index: 1100;
}
Expand Down
2 changes: 2 additions & 0 deletions src/MainLayout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState } from "react";
import { Outlet, Link, useLocation, useNavigate } from "react-router-dom";
import { Layout, Menu, Dropdown } from "antd";
import WalletConnectButton from "./components/molecules/MetamaskStatusButton/WalletConnectButton";
import Footer from "./components/molecules/Footer/Footer";

import "antd/dist/antd.css";
import "./App.scss";
Expand Down Expand Up @@ -87,6 +88,7 @@ export default function MainLayout() {
<Outlet />
</div>
</Content>
<Footer />
</Layout>
</div>
);
Expand Down
60 changes: 60 additions & 0 deletions src/components/molecules/Footer/Footer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react';
import styles from './Footer.module.scss';

const FOOTER_LINKS = [
{
label: 'Website',
href: 'https://stability.nexus',
},
{
label: 'Docs',
href: 'https://docs.stability.nexus/djed-stablecoin-protocols/djed-overview',
},
{
label: 'GitHub',
href: 'https://github.com/DjedAlliance/Djed-Solidity',
},
// Placeholder links - uncomment and add real URLs when available
// {
// label: 'Discord',
// href: 'https://discord.gg/your-invite-link',
// },
// {
// label: 'X',
// href: 'https://x.com/your-profile',
// },
// {
// label: 'LinkedIn',
// href: 'https://linkedin.com/company/your-page',
// },
];

export default function Footer() {
// Filter out any placeholder or invalid links
const validLinks = FOOTER_LINKS.filter(link => link.href && link.href !== '#' && link.href.startsWith('http'));

return (
<footer className={styles.footer} aria-label="Site footer">
<div className={styles.container}>
<div className={styles.copyright}>
© 2025 The Stable Order
</div>
<nav className={styles.links} aria-label="Footer navigation">
{validLinks.map((link, index) => (
<React.Fragment key={link.label}>
{index > 0 && <span className={styles.separator} aria-hidden="true">·</span>}
<a
href={link.href}
target="_blank"
rel="noopener noreferrer"
className={styles.link}
>
{link.label}
</a>
</React.Fragment>
))}
</nav>
</div>
</footer>
);
}
69 changes: 69 additions & 0 deletions src/components/molecules/Footer/Footer.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
@import "../../../scss/_general_styling.scss";

.footer {
width: 100%;
margin-top: auto;
border-top: 1px solid rgba(255, 255, 255, 0.08);
font-family: "Montserrat", sans-serif;
background: transparent;
}

.container {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1.5rem 3rem;
max-width: 1440px;
margin: 0 auto;

@media (max-width: 768px) {
flex-direction: column;
gap: 1rem;
padding: 2rem;
text-align: center;
}
}

.copyright {
font-size: 0.875rem;
font-weight: 400;
color: $grey-5;
}

.links {
display: flex;
align-items: center;
gap: 0.5rem;
flex-wrap: wrap;

@media (max-width: 768px) {
justify-content: center;
}
}

.link {
font-size: 0.875rem;
font-weight: 500;
color: $grey-5;
text-decoration: none;
transition: color 0.2s ease;

&:hover,
&:focus {
color: var(--gold-dark);
text-decoration: underline;
}

&:focus-visible {
outline: 2px solid var(--gold-dark);
outline-offset: 2px;
border-radius: 2px;
}
}

.separator {
font-size: 0.875rem;
color: $grey-5;
user-select: none;
opacity: 0.5;
}
Loading