diff --git a/package.json b/package.json index 934fdd4a..0bd5997b 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,7 @@ "html-to-image": "^1.11.13", "http-status-codes": "^2.3.0", "lucide-svelte": "^0.536.0", + "mailersend": "^2.6.0", "maplibre-gl": "~5.10.0", "maplibregl-mapbox-request-transformer": "^0.0.2", "micromark": "^4.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ab94c163..f77a2d7a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -62,6 +62,9 @@ importers: lucide-svelte: specifier: ^0.536.0 version: 0.536.0(svelte@4.2.20) + mailersend: + specifier: ^2.6.0 + version: 2.6.0 maplibre-gl: specifier: ~5.10.0 version: 5.10.0 @@ -1750,6 +1753,10 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + agentkeepalive@4.6.0: resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} engines: {node: '>= 8.0.0'} @@ -1848,6 +1855,10 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + callsite@1.0.0: resolution: {integrity: sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==} @@ -1960,6 +1971,10 @@ packages: engines: {node: '>=4'} hasBin: true + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -2227,6 +2242,10 @@ packages: picomatch: optional: true + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -2279,6 +2298,10 @@ packages: resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==} engines: {node: '>= 12.20'} + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -2287,6 +2310,10 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + gaxios@6.7.1: + resolution: {integrity: sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==} + engines: {node: '>=14'} + geojson-vt@4.0.2: resolution: {integrity: sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==} @@ -2381,6 +2408,10 @@ packages: http-status-codes@2.3.0: resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==} + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + human-id@4.1.3: resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} hasBin: true @@ -2465,6 +2496,10 @@ packages: resolution: {integrity: sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==} engines: {node: '>=10'} + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2472,6 +2507,9 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isomorphic-unfetch@4.0.2: + resolution: {integrity: sha512-1Yd+CF/7al18/N2BDbsLBcp6RO3tucSW+jcLq24dqdX5MNbCNTw1z4BsGsp4zNmjr/Izm2cs/cEqZPp4kvWSCA==} + jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -2608,6 +2646,9 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + mailersend@2.6.0: + resolution: {integrity: sha512-YX2Gyc6Wyw4Q4IsJ4np2Reof8nFWQ2OP/yXZTZcGCz4B7B1BOAYs71Kjb1uNRTTfDChP7rzzWBoOaX6iNlvPAg==} + map-obj@4.3.0: resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} engines: {node: '>=8'} @@ -2853,6 +2894,10 @@ packages: encoding: optional: true + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-stream-zip@1.15.0: resolution: {integrity: sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==} engines: {node: '>=0.12.0'} @@ -2873,6 +2918,10 @@ packages: number-flow@0.5.8: resolution: {integrity: sha512-FPr1DumWyGi5Nucoug14bC6xEz70A1TnhgSHhKyfqjgji2SOTz+iLJxKtv37N5JyJbteGYCm6NQ9p1O4KZ7iiA==} + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + onetime@6.0.0: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} @@ -3049,6 +3098,10 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qs@6.14.1: + resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} + engines: {node: '>=0.6'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -3150,6 +3203,22 @@ packages: resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -3380,6 +3449,9 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + unfetch@5.0.0: + resolution: {integrity: sha512-3xM2c89siXg0nHvlmYsQ2zkLASvVMBisZm5lF3gFDqfF2xonNStDJyMpvaOBe0a1Edxmqrf2E0HBdmy9QyZaeg==} + unicorn-magic@0.1.0: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} @@ -3454,6 +3526,10 @@ packages: resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} hasBin: true + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + vfile-message@2.0.4: resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} @@ -3551,6 +3627,10 @@ packages: resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} engines: {node: 20 || >=22} + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + web-streams-polyfill@4.0.0-beta.3: resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} engines: {node: '>= 14'} @@ -4853,6 +4933,8 @@ snapshots: acorn@8.15.0: {} + agent-base@7.1.4: {} + agentkeepalive@4.6.0: dependencies: humanize-ms: 1.2.1 @@ -4957,6 +5039,11 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + callsite@1.0.0: {} callsites@3.1.0: {} @@ -5056,6 +5143,8 @@ snapshots: cssesc@3.0.0: {} + data-uri-to-buffer@4.0.1: {} + debug@4.4.3: dependencies: ms: 2.1.3 @@ -5410,6 +5499,11 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -5459,11 +5553,26 @@ snapshots: node-domexception: 1.0.0 web-streams-polyfill: 4.0.0-beta.3 + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + fsevents@2.3.3: optional: true function-bind@1.1.2: {} + gaxios@6.7.1: + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6 + is-stream: 2.0.1 + node-fetch: 2.7.0 + uuid: 9.0.1 + transitivePeerDependencies: + - encoding + - supports-color + geojson-vt@4.0.2: {} get-east-asian-width@1.4.0: {} @@ -5551,6 +5660,13 @@ snapshots: http-status-codes@2.3.0: {} + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + human-id@4.1.3: {} human-signals@5.0.0: {} @@ -5604,10 +5720,17 @@ snapshots: is-retry-allowed@2.2.0: {} + is-stream@2.0.1: {} + is-stream@3.0.0: {} isexe@2.0.0: {} + isomorphic-unfetch@4.0.2: + dependencies: + node-fetch: 3.3.2 + unfetch: 5.0.0 + jiti@2.6.1: {} jpeg-js@0.4.4: {} @@ -5742,6 +5865,15 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + mailersend@2.6.0: + dependencies: + gaxios: 6.7.1 + isomorphic-unfetch: 4.0.2 + qs: 6.14.1 + transitivePeerDependencies: + - encoding + - supports-color + map-obj@4.3.0: {} maplibre-gl@5.10.0: @@ -6168,6 +6300,12 @@ snapshots: dependencies: whatwg-url: 5.0.0 + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + node-stream-zip@1.15.0: {} npm-normalize-package-bin@3.0.1: {} @@ -6191,6 +6329,8 @@ snapshots: dependencies: esm-env: 1.2.2 + object-inspect@1.13.4: {} + onetime@6.0.0: dependencies: mimic-fn: 4.0.0 @@ -6361,6 +6501,10 @@ snapshots: punycode@2.3.1: {} + qs@6.14.1: + dependencies: + side-channel: 1.1.0 + queue-microtask@1.2.3: {} quickselect@3.0.0: {} @@ -6505,6 +6649,34 @@ snapshots: shell-quote@1.8.3: {} + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} signal-exit@4.1.0: {} @@ -6733,6 +6905,8 @@ snapshots: undici-types@7.16.0: {} + unfetch@5.0.0: {} + unicorn-magic@0.1.0: {} unicorn-magic@0.4.0: {} @@ -6830,6 +7004,8 @@ snapshots: uuid@11.1.0: {} + uuid@9.0.1: {} + vfile-message@2.0.4: dependencies: '@types/unist': 2.0.11 @@ -6938,6 +7114,8 @@ snapshots: walk-up-path@4.0.0: {} + web-streams-polyfill@3.3.3: {} + web-streams-polyfill@4.0.0-beta.3: {} webidl-conversions@3.0.1: {} diff --git a/src/lib/redirects.ts b/src/lib/redirects.ts index 7f758b5b..b8ce555d 100644 --- a/src/lib/redirects.ts +++ b/src/lib/redirects.ts @@ -21,7 +21,8 @@ const REDIRECTS: Record = { '/polls': '/polls-and-surveys', '/surveys': '/polls-and-surveys', '/stipends': '/volunteer-stipends', - '/volunteer-vacancies': '/join#volunteer-vacancies' + '/volunteer-vacancies': '/join#volunteer-vacancies', + '/contact': '/contact-us' } /** Temporary redirects (302) - for time-limited campaigns, A/B tests, etc. */ diff --git a/src/posts/partnerships.md b/src/posts/partnerships.md index bb00eb46..85bf832b 100644 --- a/src/posts/partnerships.md +++ b/src/posts/partnerships.md @@ -100,6 +100,4 @@ PauseAI offers unique benefits to a variety of organizations and individuals, en - **Grassroots Feedback:** Gather ground-level feedback on AI safety programs. - **Cross-border Collaboration:** Connect local activists with global initiatives. -## Interested in exploring partnership opportunities? - -Send an email to [joep@pauseai.info](mailto:joep@pauseai.info). +Interested in exploring partnership opportunities? Check out our [Contact form](/contact-us?tab=partnerships). diff --git a/src/posts/press.md b/src/posts/press.md index 43de12d1..c72d7d84 100644 --- a/src/posts/press.md +++ b/src/posts/press.md @@ -2,9 +2,7 @@ title: PauseAI Press materials & media coverage --- -## Contact - -Maxime Fournes ([press@pauseai.info](mailto:press@pauseai.info)) +If you want to contact us, use our [Contact form](/contact-us?tab=media) ## Logo, materials diff --git a/src/routes/contact-us/+page.server.ts b/src/routes/contact-us/+page.server.ts new file mode 100644 index 00000000..4de59023 --- /dev/null +++ b/src/routes/contact-us/+page.server.ts @@ -0,0 +1,172 @@ +import { fail } from '@sveltejs/kit' +import type { Actions } from './$types' +import { env } from '$env/dynamic/private' +import { MailerSend, EmailParams, Sender, Recipient } from 'mailersend' + +export const prerender = false + +const mailersend = new MailerSend({ + apiKey: env.MAILERSEND_API_KEY || '' +}) +// a +async function sendContactEmail(data: { + name: string + email: string + subject: string + message: string + type: 'Standard' | 'Media' | 'Partnerships' | 'Feedback' + organization?: string +}) { + const sentFrom = new Sender('info@pauseai.info', 'PauseAI Contact Form') + const recipientEmail = 'patriciovercesi@gmail.com' + const recipients = [new Recipient(recipientEmail, 'PauseAI Team')] + + let htmlContent = ` +

Name: ${data.name}

+

Email: ${data.email}

+

Subject: ${data.subject}

+ ` + + if (data.organization) { + htmlContent += `

Organization: ${data.organization}

` + } + + htmlContent += `

Message:

${data.message.replace(/\n/g, '
')}

` + + const emailParams = new EmailParams() + .setFrom(sentFrom) + .setTo(recipients) + .setSubject(`[Contact Form] ${data.subject}`) + .setHtml(htmlContent) + .setText( + `Name: ${data.name}\nEmail: ${data.email}\nSubject: ${data.subject}${data.organization ? `\nOrganization: ${data.organization}` : ''}\n\nMessage:\n${data.message}` + ) + + if (data.email) { + emailParams.setReplyTo(new Recipient(data.email, data.name)) + } + + try { + await mailersend.email.send(emailParams) + return { success: true } + } catch (error: unknown) { + console.error('MailerSend Error:', JSON.stringify(error, null, 2)) + + // Extract specific error message if available from MailerSend + let errorMessage = 'Failed to send email. Please try again later.' + const err = error as { body?: { message?: string }; message?: string } + if (err.body?.message) { + errorMessage = err.body.message.replace('reply to.email', 'email') + } else if (err.message) { + errorMessage = err.message.replace('reply to.email', 'email') + } + + return { success: false, message: errorMessage } + } +} +export const actions: Actions = { + standard: async ({ request }) => { + const data = await request.formData() + const name = data.get('name')?.toString() + const email = data.get('email')?.toString() + const subject = data.get('subject')?.toString() + const message = data.get('message')?.toString() + + if (!name || !email || !subject || !message) { + return fail(400, { message: 'Missing required fields' }) + } + + const result = await sendContactEmail({ + name, + email, + subject, + message, + type: 'Standard' + }) + + if (!result.success) { + return fail(500, { message: result.message }) + } + + return { success: true } + }, + media: async ({ request }) => { + const data = await request.formData() + const name = data.get('name')?.toString() + const email = data.get('email')?.toString() + const subject = data.get('subject')?.toString() + const organization = data.get('organization')?.toString() + const details = data.get('details')?.toString() + + if (!name || !email || !subject || !organization || !details) { + return fail(400, { message: 'Missing required fields' }) + } + + const result = await sendContactEmail({ + name, + email, + subject, + message: details, + organization, + type: 'Media' + }) + + if (!result.success) { + return fail(500, { message: result.message }) + } + + return { success: true } + }, + partnerships: async ({ request }) => { + const data = await request.formData() + const name = data.get('name')?.toString() + const email = data.get('email')?.toString() + const organization = data.get('organization')?.toString() + const subject = data.get('subject')?.toString() + const message = data.get('message')?.toString() + + if (!name || !email || !organization || !subject || !message) { + return fail(400, { message: 'Missing required fields' }) + } + + const result = await sendContactEmail({ + name, + email, + organization, + subject, + message, + type: 'Partnerships' + }) + + if (!result.success) { + return fail(500, { message: result.message }) + } + + return { success: true } + }, + feedback: async ({ request }) => { + const data = await request.formData() + const name = data.get('name')?.toString() || 'Anonymous' + const email = data.get('email')?.toString() || '' + const subject = data.get('subject')?.toString() + const message = data.get('message')?.toString() + + if (!subject || !message) { + return fail(400, { message: 'Missing required fields' }) + } + + const result = await sendContactEmail({ + name, + email, + subject, + message, + type: 'Feedback' + }) + + if (!result.success) { + return fail(500, { message: result.message }) + } + + return { success: true } + } +} diff --git a/src/routes/contact-us/+page.svelte b/src/routes/contact-us/+page.svelte new file mode 100644 index 00000000..607ec804 --- /dev/null +++ b/src/routes/contact-us/+page.svelte @@ -0,0 +1,515 @@ + + + + Contact Us | PauseAI + + + +
+

Contact Us

+

Get in touch with the PauseAI team

+ +
+ + + + +
+ +
+ {#if activeTab === 'standard'} +
+
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+ {:else if activeTab === 'media'} +
+

+ Looking for press materials or media coverage? Check out our press page. +

+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+ {:else if activeTab === 'partnerships'} +
+

+ Interested in collaborating? Read about our partnership opportunities. +

+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+ {:else if activeTab === 'feedback'} +
+

+ We value your feedback! Let us know how we can improve or what you think about our work. + Providing your name and email is optional. +

+
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+ {/if} +
+
+ + diff --git a/src/routes/footer.svelte b/src/routes/footer.svelte index ce29037d..93bee22d 100644 --- a/src/routes/footer.svelte +++ b/src/routes/footer.svelte @@ -19,9 +19,7 @@

{m.footer_info()}

{m.footer_info_about()} - {m.footer_info_faq()} - {m.footer_info_proposal()} - {m.footer_info_learn()} + Contact Us {m.footer_info_press()} {m.footer_info_teams()} {m.footer_info_partnerships()} @@ -68,9 +66,7 @@ {m.footer_other_license()} - {m.footer_other_feedback()} + {m.footer_other_feedback()}