diff --git a/packages/cookieWall/CHANGELOG.md b/packages/cookieWall/CHANGELOG.md new file mode 100644 index 0000000..4f82f37 --- /dev/null +++ b/packages/cookieWall/CHANGELOG.md @@ -0,0 +1,28 @@ +# @musica-sacra/dummy + +## 0.0.4 + +### Patch Changes + +- 0060d92: Fix the title in the storybook story + +## 0.0.3 + +### Patch Changes + +- b21c866: Fix story title + +## 0.0.2 + +### Patch Changes + +- 7cac3b8: Add example change to dummy text. + - **What** Add example change to dummy text + - **Why** Want to release new patch version + - **How** Nothing. + +## 0.0.1 + +### Patch Changes + +- 4c24fd0: First publish of dummy diff --git a/packages/cookieWall/README.md b/packages/cookieWall/README.md new file mode 100644 index 0000000..d2b7061 --- /dev/null +++ b/packages/cookieWall/README.md @@ -0,0 +1,10 @@ +# @musica-sacra/cookie-wall + +A lightweight and customizable React component for displaying a cookie consent wall that helps you manage user privacy preferences in compliance with GDPR and similar regulations. + +## Installation + +`npm install @musica-sacra/cookie-wall` + +## Basic Usage + diff --git a/packages/cookieWall/package.json b/packages/cookieWall/package.json new file mode 100644 index 0000000..08fc03b --- /dev/null +++ b/packages/cookieWall/package.json @@ -0,0 +1,40 @@ +{ + "name": "@musica-sacra/cookie-wall", + "version": "0.0.1", + "description": "CookieWall react plugin", + "main": "dist/index.js", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "scripts": { + "build": "rollup -c --bundleConfigAsCjs", + "test": "echo \"Error: no test specified\" && exit 1", + "lint": "eslint src --ext .ts,.tsx", + "lint:fix": "eslint src --ext .ts,.tsx --fix", + "clean": "rm -rf dist" + }, + "author": "Lukáš Zeleňák", + "license": "ISC", + "files": [ + "dist" + ], + "keywords": [ + "musica-sacra", + "musica", + "sacra", + "cookieWall" + ], + "publishConfig": { + "access": "public" + }, + "dependencies": {}, + "devDependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0", + "tslib": "^2.8.1", + "typescript": "^5.8.2" + }, + "peerDependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0" + } +} \ No newline at end of file diff --git a/packages/cookieWall/rollup.config.js b/packages/cookieWall/rollup.config.js new file mode 100644 index 0000000..c5f8479 --- /dev/null +++ b/packages/cookieWall/rollup.config.js @@ -0,0 +1,3 @@ +import { createBaseConfig, createTypeConfig } from '../../rollup.config.base'; + +export default [createBaseConfig(), createTypeConfig()]; diff --git a/packages/cookieWall/src/component/dummy/CookieWall.tsx b/packages/cookieWall/src/component/dummy/CookieWall.tsx new file mode 100644 index 0000000..696c285 --- /dev/null +++ b/packages/cookieWall/src/component/dummy/CookieWall.tsx @@ -0,0 +1,55 @@ +import { Button } from '@musica-sacra/forms'; +import '@musica-sacra/forms/dist/components/button/button.scss'; +import { useBem } from '@musica-sacra/hooks'; +import { useCookiesConsent } from '../../context/cookieConsentContextProvider'; + +type CookieWallProps = { + className?: string; +}; + +export function CookieWall({ className = '' }: CookieWallProps) { + const { cookieConsent, acceptCookiesConsent, rejectCookiesConsent } = useCookiesConsent(); + if (cookieConsent !== undefined) { + return null; + } + + const { bem, base } = useBem('ms-cookie-wall'); + + return ( +
+
+
+
+ + Lorem ipsum dolor sit amet consectetur adipisicing + elit. Officiis eveniet nam sunt culpa! Reiciendis + neque ratione assumenda blanditiis similique autem + dolores ut earum at eveniet nemo laudantium, nihil + sint a. + +
    +
  • Deliver and maintain Google services
  • +
  • + Track outages and protect against spam, fraud, + and abuse +
  • +
  • + Measure audience engagement and site statistics + to understand how our services are used and + enhance the quality of those services +
  • +
+
+
+ + +
+
+
+
+ ); +} diff --git a/packages/cookieWall/src/component/dummy/__tests__/Dummy.stories.ts b/packages/cookieWall/src/component/dummy/__tests__/Dummy.stories.ts new file mode 100644 index 0000000..51f3aec --- /dev/null +++ b/packages/cookieWall/src/component/dummy/__tests__/Dummy.stories.ts @@ -0,0 +1,15 @@ +import { Dummy } from '@musica-sacra/dummy'; +import { StoryObj } from '@storybook/react'; + +const meta = { + title: '@musica-sacra/Dummy/components/Dummy', + component: Dummy, + args: { + dummyText: 'Dummy text', + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/packages/cookieWall/src/component/dummy/cookieWall.scss b/packages/cookieWall/src/component/dummy/cookieWall.scss new file mode 100644 index 0000000..9b273a1 --- /dev/null +++ b/packages/cookieWall/src/component/dummy/cookieWall.scss @@ -0,0 +1,65 @@ +@use "../../../src/styles/variables" as *; + +.ms-cookie-wall { + position: fixed; + bottom: 0; + left: 0; + width: 100%; + background-color: $background-primary; + border-top: $border-light; + z-index: 1000; + + &__ { + &container { + max-width: $content-width; + margin: 0 auto; + padding: 20px 0px; + + @media (max-width: $break-point-small-desktop) { + text-align: left; + padding: 20px; + } + } + + &content { + display: flex; + flex-direction: column; + gap: 15px; + } + + &text { + flex: 1; + + span { + font-size: 14px; + line-height: 1.4; + color: $secondary; + } + } + + &list { + list-style: disc; + margin: 10px 0 0 0; + padding-left: 20px; + font-size: 14px; + line-height: 1.4; + color: $secondary; + + li { + margin-bottom: 5px; + } + } + + &buttons { + display: flex; + gap: 10px; + justify-content: flex-end; + align-self: flex-end; + + @media (max-width: $break-point-tablet) { + justify-content: right; + align-self: right; + } + } + } +} diff --git a/packages/cookieWall/src/context/cookieConsentContextProvider.tsx b/packages/cookieWall/src/context/cookieConsentContextProvider.tsx new file mode 100644 index 0000000..9370370 --- /dev/null +++ b/packages/cookieWall/src/context/cookieConsentContextProvider.tsx @@ -0,0 +1,67 @@ +import React, { createContext, useCallback, useContext, useEffect, useState, ReactNode } from 'react'; + +const STORAGE_KEY = 'ms_cookie_consent'; + +type CookieConsent = boolean | undefined; + +type CookieConsentContextValue = { + cookieConsent: CookieConsent; + acceptCookiesConsent: () => void; + rejectCookiesConsent: () => void; + isCookiesConsentSet: () => boolean; +}; + +const defaultContextValue: CookieConsentContextValue = { + cookieConsent: undefined, + acceptCookiesConsent: () => {}, + rejectCookiesConsent: () => {}, + isCookiesConsentSet: () => false, +}; + +export const CookieConsentContext = createContext(defaultContextValue); + +export function CookieConsentContextProvider({ children }: { children: ReactNode }) { + const [cookieConsent, setCookieConsent] = useState(defaultContextValue.cookieConsent); + + useEffect(() => { + try { + const raw = localStorage.getItem(STORAGE_KEY); + if (raw === 'true') setCookieConsent(true); + else if (raw === 'false') setCookieConsent(false); + else setCookieConsent(undefined); + } catch { + setCookieConsent(undefined); + } + }, []); + + const acceptCookiesConsent = useCallback(() => { + try { + localStorage.setItem(STORAGE_KEY, 'true'); + } catch { + } + setCookieConsent(true); + }, []); + + const rejectCookiesConsent = useCallback(() => { + try { + localStorage.setItem(STORAGE_KEY, 'false'); + localStorage.removeItem(STORAGE_KEY); + } catch { + } + setCookieConsent(false); + }, []); + + const isCookiesConsentSet = useCallback(() => cookieConsent !== undefined, [cookieConsent]); + + return ( + + {children} + + ); +} + +export function useCookiesConsent() { + return useContext(CookieConsentContext); +} \ No newline at end of file diff --git a/packages/cookieWall/src/main.ts b/packages/cookieWall/src/main.ts new file mode 100644 index 0000000..eaa9e8a --- /dev/null +++ b/packages/cookieWall/src/main.ts @@ -0,0 +1 @@ +export { CookieWall } from './component/dummy/CookieWall'; diff --git a/packages/cookieWall/tsconfig.json b/packages/cookieWall/tsconfig.json new file mode 100644 index 0000000..3d4d00f --- /dev/null +++ b/packages/cookieWall/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "dist", + }, + "include": ["src"] +} \ No newline at end of file