B2B-88: add starter kit structure and elements

This commit is contained in:
devmc-ee
2025-06-08 16:18:30 +03:00
parent 657a36a298
commit e7b25600cb
1280 changed files with 77893 additions and 5688 deletions

View File

@@ -0,0 +1,118 @@
'use client';
import { useCallback, useMemo, useState } from 'react';
import * as DialogPrimitive from '@radix-ui/react-dialog';
import { Button } from '../shadcn/button';
import { Heading } from '../shadcn/heading';
import { Trans } from './trans';
// configure this as you wish
const COOKIE_CONSENT_STATUS = 'cookie_consent_status';
enum ConsentStatus {
Accepted = 'accepted',
Rejected = 'rejected',
Unknown = 'unknown',
}
export function CookieBanner() {
const { status, accept, reject } = useCookieConsent();
if (!isBrowser()) {
return null;
}
if (status !== ConsentStatus.Unknown) {
return null;
}
return (
<DialogPrimitive.Root open modal={false}>
<DialogPrimitive.Content
onOpenAutoFocus={(e) => e.preventDefault()}
className={`dark:shadow-primary-500/40 bg-background animate-in fade-in zoom-in-95 slide-in-from-bottom-16 fill-mode-both fixed bottom-0 w-full max-w-lg border p-6 shadow-2xl delay-1000 duration-1000 lg:bottom-[2rem] lg:left-[2rem] lg:h-48 lg:rounded-lg`}
>
<div className={'flex flex-col space-y-4'}>
<div>
<Heading level={3}>
<Trans i18nKey={'cookieBanner.title'} />
</Heading>
</div>
<div className={'text-gray-500 dark:text-gray-400'}>
<Trans i18nKey={'cookieBanner.description'} />
</div>
<div className={'flex justify-end space-x-2.5'}>
<Button variant={'ghost'} onClick={reject}>
<Trans i18nKey={'cookieBanner.reject'} />
</Button>
<Button autoFocus onClick={accept}>
<Trans i18nKey={'cookieBanner.accept'} />
</Button>
</div>
</div>
</DialogPrimitive.Content>
</DialogPrimitive.Root>
);
}
export function useCookieConsent() {
const initialState = getStatusFromLocalStorage();
const [status, setStatus] = useState<ConsentStatus>(initialState);
const accept = useCallback(() => {
const status = ConsentStatus.Accepted;
setStatus(status);
storeStatusInLocalStorage(status);
}, []);
const reject = useCallback(() => {
const status = ConsentStatus.Rejected;
setStatus(status);
storeStatusInLocalStorage(status);
}, []);
const clear = useCallback(() => {
const status = ConsentStatus.Unknown;
setStatus(status);
storeStatusInLocalStorage(status);
}, []);
return useMemo(() => {
return {
clear,
status,
accept,
reject,
};
}, [clear, status, accept, reject]);
}
function storeStatusInLocalStorage(status: ConsentStatus) {
if (!isBrowser()) {
return;
}
localStorage.setItem(COOKIE_CONSENT_STATUS, status);
}
function getStatusFromLocalStorage() {
if (!isBrowser()) {
return ConsentStatus.Unknown;
}
const status = localStorage.getItem(COOKIE_CONSENT_STATUS) as ConsentStatus;
return status ?? ConsentStatus.Unknown;
}
function isBrowser() {
return typeof window !== 'undefined';
}