Skip to content
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ changes.

### Added

- Add maintenance ending banner [Issue 3647](https://github.com/IntersectMBO/govtool/issues/3647)

### Fixed

### Changed
Expand All @@ -20,7 +22,6 @@ changes.

## [v2.0.22](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.22) 2025-05-15


### Added

### Fixed
Expand Down
106 changes: 106 additions & 0 deletions govtool/frontend/src/components/organisms/MaintenanceEndingBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Box, Typography, IconButton } from "@mui/material";
import { useState } from "react";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
import { Trans, useTranslation } from "react-i18next";

export const MaintenanceEndingBanner = () => {
const [isExpanded, setIsExpanded] = useState(true);
const { t } = useTranslation();

const handleToggle = () => {
setIsExpanded((prev) => !prev);
};

return (
<Box
sx={{
backgroundColor: "#9c2224",
width: "100%",
overflow: "hidden",
transition: "all 0.3s ease-in-out",
}}
>
{/* Banner Header */}
<Box
sx={{
px: 2,
py: 1,
textAlign: "left",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Typography
variant="body2"
fontWeight={600}
color="common.white"
sx={{ display: "flex", alignItems: "center" }}
>
{t("system.maintenanceEnding.title")}
</Typography>
</Box>
<Box sx={{ display: "flex" }}>
<IconButton
onClick={handleToggle}
size="small"
data-testid="toggle-maintenance-banner"
sx={{
color: "white",
transition: "transform 0.3s ease",
}}
>
{isExpanded ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</Box>
</Box>

{/* Expandable Content */}
<Box
sx={{
maxHeight: isExpanded ? "500px" : "0px",
transition: "max-height 0.3s ease-in-out",
overflow: "hidden",
}}
>
<Box
sx={{
px: 2,
pb: 2,
color: "white",
display: "flex",
flexDirection: "column",
}}
>
<Typography
fontWeight={600}
variant="caption"
color="common.white"
mb={0.5}
>
{t("system.maintenanceEnding.description1")}
</Typography>
<Typography variant="caption" color="common.white" mb={0.5}>
<Trans
i18nKey="system.maintenanceEnding.description2"
components={[
<Typography
key="1"
variant="caption"
fontWeight={600}
color="common.white"
component="span"
/>,
]}
/>
</Typography>
<Typography variant="caption" color="common.white">
{t("system.maintenanceEnding.description3")}
</Typography>
</Box>
</Box>
</Box>
);
};
126 changes: 73 additions & 53 deletions govtool/frontend/src/components/organisms/TopBanners.tsx
Original file line number Diff line number Diff line change
@@ -1,77 +1,97 @@
import { Box, Link, Typography } from "@mui/material";
import { Trans, useTranslation } from "react-i18next";
import { useAppContext } from "@/context";
import { useAppContext, useCardano } from "@/context";
import { LINKS } from "@/consts/links";
import { MaintenanceEndingBanner } from "./MaintenanceEndingBanner";

export const TopBanners = () => {
const { isMainnet, networkName, isInBootstrapPhase, isAppInitializing } =
useAppContext();
const { isEnabled } = useCardano();
const { t } = useTranslation();

if (isAppInitializing) {
return null;
}

return (
<Box position="relative">
{/* NETWORK BANNER */}
{!isMainnet && (
<Box
sx={{
backgroundColor: "#BBE3F0",
px: 2,
py: 0.5,
display: "flex",
justifyContent: "center",
gap: 1,
}}
data-testid="system-network-name"
>
<Typography variant="caption" fontWeight={600} color="primary">
{`${t("network")}: ${networkName}`}
</Typography>
<Typography variant="caption" fontWeight={600} color="primary">
|
</Typography>
<Link
variant="caption"
fontWeight={600}
color="primary"
href="https://gov.tools/"
<>
<Box>
{/* NETWORK BANNER */}
{!isMainnet && (
<Box
sx={{
backgroundColor: "#BBE3F0",
px: 2,
py: 0.5,
display: "flex",
justifyContent: "center",
gap: 1,
}}
data-testid="system-network-name"
>
{t("goToMainnet")}
</Link>
</Box>
)}
<Typography variant="caption" fontWeight={600} color="primary">
{`${t("network")}: ${networkName}`}
</Typography>
<Typography variant="caption" fontWeight={600} color="primary">
|
</Typography>
<Link
variant="caption"
fontWeight={600}
color="primary"
href="https://gov.tools/"
>
{t("goToMainnet")}
</Link>
</Box>
)}
</Box>

{/* BOOTSTRAPPING BANNER */}
{isInBootstrapPhase && (
{/* GOVTOOL MAINTENANCE ENDING SOON BANNER */}
{isEnabled && (
<Box
sx={{
backgroundColor: "#1136A6",
px: 2,
py: 1,
textAlign: "center",
position: "sticky",
top: 0,
width: "100%",
zIndex: 1200,
}}
data-testid="system-bootstrapping-warning"
>
<Typography variant="caption" fontWeight={600} color="common.white">
<Trans
i18nKey="system.bootstrappingWarning"
components={{
docs: (
<Link
href={LINKS.BOOTSTRAPPING_PHASE}
target="_blank"
color="common.white"
data-testid="system-bootstrapping-warning-link"
/>
),
}}
/>
</Typography>
<MaintenanceEndingBanner />
</Box>
)}
</Box>

{/* BOOTSTRAPPING BANNER */}
<Box>
{isInBootstrapPhase && (
<Box
sx={{
backgroundColor: "#1136A6",
px: 2,
py: 1,
textAlign: "center",
}}
data-testid="system-bootstrapping-warning"
>
<Typography variant="caption" fontWeight={600} color="common.white">
<Trans
i18nKey="system.bootstrappingWarning"
components={{
docs: (
<Link
href={LINKS.BOOTSTRAPPING_PHASE}
target="_blank"
color="common.white"
data-testid="system-bootstrapping-warning-link"
/>
),
}}
/>
</Typography>
</Box>
)}
</Box>
</>
);
};
88 changes: 46 additions & 42 deletions govtool/frontend/src/components/organisms/TopNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import { useCardano, useFeatureFlag, useModal } from "@context";
import { useScreenDimension, useTranslation } from "@hooks";
import { openInNewTab } from "@utils";
import { DrawerMobile } from "./DrawerMobile";
import { MaintenanceEndingBanner } from "./MaintenanceEndingBanner";

const POSITION_TO_BLUR = 50;
const POSITION_TO_BLUR = 80;

export const TopNav = ({ isConnectButton = true }) => {
const {
Expand Down Expand Up @@ -136,51 +137,54 @@ export const TopNav = ({ isConnectButton = true }) => {
);

return (
<AppBar
ref={containerRef}
color="transparent"
sx={{
alignItems: "center",
backdropFilter: shouldBlur ? "blur(10px)" : "none",
backgroundColor: shouldBlur
? "rgba(256, 256, 256, 0.7)"
: isMobile
? "white"
: "transparent",
borderBottom: isMobile ? 1 : 0,
borderColor: "lightblue",
boxShadow: 0,
justifyContent: "center",
flexDirection: "row",
position: "sticky",
top: 0,
px: isMobile ? 2 : 5,
py: 3,
zIndex: 100,
}}
>
<Box
<Box sx={{ position: "sticky", top: 0, zIndex: 100, width: "100%" }}>
<MaintenanceEndingBanner />

<AppBar
ref={containerRef}
position="static"
elevation={0}
sx={{
display: "flex",
alignItems: "center",
flex: 1,
justifyContent: "space-between",
maxWidth: 1290,
// TODO: Fix shouldBlur to work with sticky
backdropFilter: shouldBlur ? "blur(10px)" : "none",
backgroundColor: shouldBlur
? "rgba(256, 256, 256, 0.7)"
: isMobile
? "white"
: "rgba(256, 256, 256, 0.7)",
borderBottom: isMobile ? 1 : 0,
borderColor: "lightblue",
boxShadow: 0,
justifyContent: "center",
flexDirection: "row",
px: isMobile ? 2 : 5,
py: 3,
}}
>
<NavLink
data-testid="logo-button"
to={PATHS.home}
onClick={() => isConnectButton || disconnectWallet()}
<Box
sx={{
display: "flex",
alignItems: "center",
flex: 1,
justifyContent: "space-between",
maxWidth: 1290,
}}
>
<img
alt="app-logo"
height={isMobile ? 25 : 35}
src={IMAGES.appLogo}
/>
</NavLink>
{screenWidth >= 1145 ? renderDesktopNav() : renderMobileNav()}
</Box>
</AppBar>
<NavLink
data-testid="logo-button"
to={PATHS.home}
onClick={() => isConnectButton || disconnectWallet()}
>
<img
alt="app-logo"
height={isMobile ? 25 : 35}
src={IMAGES.appLogo}
/>
</NavLink>
{screenWidth >= 1145 ? renderDesktopNav() : renderMobileNav()}
</Box>
</AppBar>
</Box>
);
};
8 changes: 7 additions & 1 deletion govtool/frontend/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,13 @@
"system": {
"description": "The Cardano GovTool is a tool that allows you to participate in the governance of the Cardano network. You can propose, vote on, and delegate your voting power to other users.",
"title": "This tool is connected to {{networkName}}",
"bootstrappingWarning": "Govtool is in the Bootstrapping phase. Some features are not available. <docs>Learn more</docs>"
"bootstrappingWarning": "Govtool is in the Bootstrapping phase. Some features are not available. <docs>Learn more</docs>",
"maintenanceEnding": {
"title": "⚠️ GovTool Maintenance Ending Soon",
"description1": "GovTool has not been included in the 2025 Cardano budget.",
"description2": "Unless alternative support is secured, <0>maintenance will end in June 2025.</0>",
"description3": "We remain committed to transparency and will keep you updated."
}
},
"tooltips": {
"delegateTodRep": {
Expand Down