diff --git a/netlify/functions/contact.js b/netlify/functions/contact.js new file mode 100644 index 0000000..ab327e2 --- /dev/null +++ b/netlify/functions/contact.js @@ -0,0 +1,30 @@ +import { JSDOM } from 'jsdom'; +import createDOMPurify from 'dompurify'; + +export const handler = async (event) => { + try { + const data = JSON.parse(event.body); + const DOMPurify = createDOMPurify(new JSDOM('').window); + + // Sanitize user input + const sanitizedData = { + name: DOMPurify.sanitize(data.name), + email: DOMPurify.sanitize(data.email), + message: DOMPurify.sanitize(data.message), + }; + + // TODO: Process the sanitized data (e.g., send an email) + console.log('Sanitized data:', sanitizedData); + + return { + statusCode: 200, + body: JSON.stringify({ message: 'Form submitted successfully!' }), + }; + } catch (error) { + console.error('Error:', error); + return { + statusCode: 500, + body: JSON.stringify({ message: 'An error occurred.' }), + }; + } +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7b08ebc..21d1442 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4016,9 +4016,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001667", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", - "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", + "version": "1.0.30001707", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz", + "integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==", "funding": [ { "type": "opencollective", @@ -4032,7 +4032,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/ccount": { "version": "2.0.1", diff --git a/src/assets/styles/tailwind.css b/src/assets/styles/tailwind.css index 04032b3..01c69d0 100644 --- a/src/assets/styles/tailwind.css +++ b/src/assets/styles/tailwind.css @@ -1,14 +1,16 @@ @tailwind base; -@tailwind components; -@tailwind utilities; + @tailwind components; + @tailwind utilities; -@layer base { - p, li, div { + @layer base { + p, + li, + div { line-height: 1.5; } -} + } -@layer utilities { + @layer utilities { .bg-page { background-color: var(--aw-color-bg-page); } @@ -24,83 +26,75 @@ .text-muted { color: var(--aw-color-text-muted); } - .content-backdrop { - @apply bg-white/20 dark:bg-gray-900/15 backdrop-blur-sm hover:bg-white/30 hover:backdrop-blur-md dark:hover:backdrop-blur-md transition-all duration-300 ease-in-out; - } - .content-card { - @apply rounded-lg p-4 md:p-6 content-backdrop; - } -} + } -@layer components { + @layer components { .btn { - @apply inline-flex items-center justify-center rounded-full border-gray-400 border bg-transparent font-medium text-center text-base text-page leading-snug transition py-3.5 px-6 md:px-8 ease-in duration-200 focus:ring-blue-500 focus:ring-offset-blue-200 focus:ring-2 focus:ring-offset-2 hover:bg-gray-100 hover:border-gray-600 dark:text-slate-300 dark:border-slate-500 dark:hover:bg-slate-800 dark:hover:border-slate-800 cursor-pointer; + @apply inline-flex items-center justify-center rounded-full border-gray-400 border bg-transparent font-medium text-center text-base text-page leading-snug transition py-3.5 px-6 md:px-8 ease-in duration-200 focus:ring-blue-500 focus:ring-offset-blue-200 focus:ring-2 focus:ring-offset-2 hover:bg-gray-100 hover:border-gray-600 dark:text-slate-300 dark:border-slate-500 dark:hover:bg-slate-800 dark:hover:border-slate-800 cursor-pointer; } .btn-primary { - @apply btn font-semibold bg-primary text-white border-primary hover:bg-secondary hover:border-secondary hover:text-white dark:text-white dark:bg-primary dark:border-primary dark:hover:border-secondary dark:hover:bg-secondary; + @apply btn font-semibold bg-primary text-white border-primary hover:bg-secondary hover:border-secondary hover:text-white dark:text-white dark:bg-primary dark:border-primary dark:hover:border-secondary dark:hover:bg-secondary; } .btn-secondary { - @apply btn; + @apply btn; } .btn-tertiary { - @apply btn border-none shadow-none text-muted hover:text-gray-900 dark:text-gray-400 dark:hover:text-white; + @apply btn border-none shadow-none text-muted hover:text-gray-900 dark:text-gray-400 dark:hover:text-white; } -} + } -#header.scroll > div:first-child { + #header.scroll > div:first-child { @apply bg-page md:bg-white/90 md:backdrop-blur-md; box-shadow: 0 0.375rem 1.5rem 0 rgb(140 152 164 / 13%); -} -.dark #header.scroll > div:first-child, -#header.scroll.dark > div:first-child { + } + .dark #header.scroll > div:first-child, + #header.scroll.dark > div:first-child { @apply bg-page md:bg-[#030621e6] border-b border-gray-500/20; box-shadow: none; -} -/* #header.scroll > div:last-child { + } + /* #header.scroll > div:last-child { @apply py-3; -} */ + } */ -#header.expanded nav { + #header.expanded nav { position: fixed; top: 70px; left: 0; right: 0; bottom: 70px !important; padding: 0 5px; -} + } -.dropdown:focus .dropdown-menu, -.dropdown:focus-within .dropdown-menu, -.dropdown:hover .dropdown-menu { + .dropdown:focus .dropdown-menu, + .dropdown:focus-within .dropdown-menu, + .dropdown:hover .dropdown-menu { display: block; -} + } -[astro-icon].icon-light > * { + [astro-icon].icon-light > * { stroke-width: 1.2; -} + } -[astro-icon].icon-bold > * { + [astro-icon].icon-bold > * { stroke-width: 2.4; -} + } -[data-aw-toggle-menu] path { + [data-aw-toggle-menu] path { @apply transition; -} -[data-aw-toggle-menu].expanded g > path:first-child { + } + [data-aw-toggle-menu].expanded g > path:first-child { @apply -rotate-45 translate-y-[15px] translate-x-[-3px]; -} + } -[data-aw-toggle-menu].expanded g > path:last-child { + [data-aw-toggle-menu].expanded g > path:last-child { @apply rotate-45 translate-y-[-8px] translate-x-[14px]; -} + } -/* To deprecated */ + /* To deprecated */ -.dd *:first-child { + .dd *:first-child { margin-top: 0; -} - - + } diff --git a/src/components/CookieBanner.astro b/src/components/CookieBanner.astro index e5ead8f..0cea04c 100644 --- a/src/components/CookieBanner.astro +++ b/src/components/CookieBanner.astro @@ -5,12 +5,18 @@ const { lang = 'en' } = Astro.params; const t = getTranslation(lang); --- -