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
4 changes: 2 additions & 2 deletions platforms/blabsy/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "tsconfig.json"
"project": true
},
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:import/typescript",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"next/core-web-vitals"
],
"settings": {
Expand Down
42 changes: 39 additions & 3 deletions platforms/blabsy/src/components/common/maintenance-banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,24 @@ interface Motd {
message: string;
}

const DISMISSED_KEY = 'maintenance-banner-dismissed';

export function MaintenanceBanner(): JSX.Element | null {
const [motd, setMotd] = useState<Motd | null>(null);
const [isDismissed, setIsDismissed] = useState(false);

useEffect(() => {
const fetchMotd = async () => {
try {
const registryUrl = process.env.NEXT_PUBLIC_REGISTRY_URL || 'http://localhost:4321';
const response = await axios.get<Motd>(`${registryUrl}/motd`);
setMotd(response.data);

// Check if this message has been dismissed
if (response.data.status === 'maintenance') {
const dismissed = localStorage.getItem(DISMISSED_KEY);
setIsDismissed(dismissed === response.data.message);
}
} catch (error) {
console.error('Failed to fetch motd:', error);
}
Expand All @@ -23,13 +32,40 @@ export function MaintenanceBanner(): JSX.Element | null {
void fetchMotd();
}, []);

if (motd?.status !== 'maintenance') {
const dismissBanner = (): void => {
if (motd?.message) {
localStorage.setItem(DISMISSED_KEY, motd.message);
setIsDismissed(true);
}
};

if (motd?.status !== 'maintenance' || isDismissed) {
return null;
}

return (
<div className='bg-yellow-500 px-4 py-3 text-center text-sm font-medium text-black'>
⚠️ {motd.message}
<div className='relative bg-yellow-500 px-4 py-3 text-center text-sm font-medium text-black'>
<span>⚠️ {motd.message}</span>
<button
onClick={dismissBanner}
className='absolute right-4 top-1/2 -translate-y-1/2 rounded p-1 hover:bg-yellow-600 focus:outline-none focus:ring-2 focus:ring-yellow-700'
aria-label='Dismiss banner'
>
<svg
className='h-4 w-4'
fill='none'
stroke='currentColor'
viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M6 18L18 6M6 6l12 12'
/>
</svg>
</button>
</div>
);
}
Expand Down
42 changes: 39 additions & 3 deletions platforms/eVoting/src/components/MaintenanceBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,24 @@ interface Motd {
message: string;
}

const DISMISSED_KEY = 'maintenance-banner-dismissed';

export function MaintenanceBanner() {
const [motd, setMotd] = useState<Motd | null>(null);
const [isDismissed, setIsDismissed] = useState(false);

useEffect(() => {
const fetchMotd = async () => {
try {
const registryUrl = process.env.NEXT_PUBLIC_REGISTRY_URL || 'http://localhost:4321';
const response = await axios.get<Motd>(`${registryUrl}/motd`);
setMotd(response.data);

// Check if this message has been dismissed
if (response.data.status === 'maintenance') {
const dismissed = localStorage.getItem(DISMISSED_KEY);
setIsDismissed(dismissed === response.data.message);
}
} catch (error) {
console.error('Failed to fetch motd:', error);
}
Expand All @@ -25,13 +34,40 @@ export function MaintenanceBanner() {
fetchMotd();
}, []);

if (motd?.status !== 'maintenance') {
const dismissBanner = () => {
if (motd?.message) {
localStorage.setItem(DISMISSED_KEY, motd.message);
setIsDismissed(true);
}
};

if (motd?.status !== 'maintenance' || isDismissed) {
return null;
}

return (
<div className="bg-yellow-500 px-4 py-3 text-center text-sm font-medium text-black">
⚠️ {motd.message}
<div className="relative bg-yellow-500 px-4 py-3 text-center text-sm font-medium text-black">
<span>⚠️ {motd.message}</span>
<button
onClick={dismissBanner}
className="absolute right-4 top-1/2 -translate-y-1/2 rounded p-1 hover:bg-yellow-600 focus:outline-none focus:ring-2 focus:ring-yellow-700"
aria-label="Dismiss banner"
>
<svg
className="h-4 w-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,24 @@ interface Motd {
message: string;
}

const DISMISSED_KEY = 'maintenance-banner-dismissed';

export function MaintenanceBanner() {
const [motd, setMotd] = useState<Motd | null>(null);
const [isDismissed, setIsDismissed] = useState(false);

useEffect(() => {
const fetchMotd = async () => {
try {
const registryUrl = process.env.NEXT_PUBLIC_REGISTRY_URL || 'http://localhost:4321';
const response = await axios.get<Motd>(`${registryUrl}/motd`);
setMotd(response.data);

// Check if this message has been dismissed
if (response.data.status === 'maintenance') {
const dismissed = localStorage.getItem(DISMISSED_KEY);
setIsDismissed(dismissed === response.data.message);
}
} catch (error) {
console.error('Failed to fetch motd:', error);
}
Expand All @@ -25,13 +34,40 @@ export function MaintenanceBanner() {
fetchMotd();
}, []);

if (motd?.status !== 'maintenance') {
const dismissBanner = () => {
if (motd?.message) {
localStorage.setItem(DISMISSED_KEY, motd.message);
setIsDismissed(true);
}
};

if (motd?.status !== 'maintenance' || isDismissed) {
return null;
}

return (
<div className="bg-yellow-500 px-4 py-3 text-center text-sm font-medium text-black">
⚠️ {motd.message}
<div className="relative bg-yellow-500 px-4 py-3 text-center text-sm font-medium text-black">
<span>⚠️ {motd.message}</span>
<button
onClick={dismissBanner}
className="absolute right-4 top-1/2 -translate-y-1/2 rounded p-1 hover:bg-yellow-600 focus:outline-none focus:ring-2 focus:ring-yellow-700"
aria-label="Dismiss banner"
>
<svg
className="h-4 w-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,60 @@
import { PUBLIC_REGISTRY_URL } from '$env/static/public';

let motd = $state<{ status: 'up' | 'maintenance'; message: string } | null>(null);
let isDismissed = $state(false);

const DISMISSED_KEY = 'maintenance-banner-dismissed';

function checkIfDismissed(message: string): boolean {
if (typeof window === 'undefined') return false;
const dismissed = localStorage.getItem(DISMISSED_KEY);
return dismissed === message;
}

function dismissBanner() {
if (motd?.message) {
localStorage.setItem(DISMISSED_KEY, motd.message);
isDismissed = true;
}
}

onMount(async () => {
try {
const registryUrl = PUBLIC_REGISTRY_URL || 'http://localhost:4321';
const response = await axios.get(`${registryUrl}/motd`);
motd = response.data;

if (motd?.status === 'maintenance') {
isDismissed = checkIfDismissed(motd.message);
}
} catch (error) {
console.error('Failed to fetch motd:', error);
}
});
</script>

{#if motd?.status === 'maintenance'}
<div class="bg-yellow-500 px-4 py-3 text-center text-sm font-medium text-black">
⚠️ {motd.message}
{#if motd?.status === 'maintenance' && !isDismissed}
<div class="relative bg-yellow-500 px-4 py-3 text-center text-sm font-medium text-black">
<span>⚠️ {motd.message}</span>
<button
onclick={dismissBanner}
class="absolute right-4 top-1/2 -translate-y-1/2 rounded p-1 hover:bg-yellow-600 focus:outline-none focus:ring-2 focus:ring-yellow-700"
aria-label="Dismiss banner"
>
<svg
class="h-4 w-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
{/if}
Loading