+ FreeSewing respects your privacy and your rights. We adhere to the toughest privacy and
+ security law in the world: the{' '}
+
+ General Data Protection Regulation
+ {' '}
+ (GDPR) of the European Union (EU).
+
+
+ Under the GDPR, processing of your personal data requires granular consent — in other words,{' '}
+ we need your permission for the various ways we handle your data.
+
+ >
+ ),
+ account: (
+
+
What is account data?
+
+ Your email address, username, and password, and any measurements{' '}
+ you add to your account.
+
+
Why do we need it?
+
+ To authenticate you, contact you when needed, and generate bespoke{' '}
+ sewing patterns.
+
+
How long do we keep it?
+
+ 12 months after the last time your connected to our backend, or until you{' '}
+ remove your account or revoke this consent.
+
+
Do we share it with others?
+
+ No, never.
+
+
+ Note: Freesewing publishes anonymized measurements as open data for scientific research. You
+ have the right to object to this.
+
+
+ ),
+ opendata: `This data is used to study and understand the human form in all its shapes,
+ so we can get better sewing patterns, and better fitting garments.
+ Even though this data is anonymized, you have the right to object to this.`,
+}
diff --git a/packages/react/components/Account/Links.mjs b/packages/react/components/Account/Links.mjs
index 26e1ccfb940..7faca7858fa 100644
--- a/packages/react/components/Account/Links.mjs
+++ b/packages/react/components/Account/Links.mjs
@@ -74,12 +74,12 @@ const itemIcons = {
const btnClasses = 'daisy-btn capitalize flex flex-row justify-between'
const itemClasses = 'flex flex-row items-center justify-between bg-opacity-10 p-2 px-4 rounded mb-1'
+const linkClasses = `hover:bg-secondary hover:bg-opacity-10 max-w-md hover:no-underline`
const titles = {
- apikeys: 'Your API Keys',
- bookmarks: 'Your Bookmarks',
- sets: 'Your Measurements Sets',
- patterns: 'Your Patterns',
+ apikeys: 'API Keys',
+ sets: 'Measurements Sets',
+ patterns: 'Patterns',
img: 'Avatar',
email: 'E-mail Address',
newsletter: 'Newsletter Subscription',
@@ -90,22 +90,12 @@ const titles = {
mfa: 'Multi-Factor Authentication',
}
-const AccountLink = ({ item, children, Link }) => (
-
- {children}
-
-)
-
const YesNo = ({ check }) => (check ? : )
const t = (input) => input
/**
- * The AccountLinks component shows all of the links to manage your account
+ * The Links component shows all of the links to manage your account
*
* @param {object} props - All the React props
* @param {function} Link - A custom Link component, typically the Docusaurus one, but it's optional
@@ -177,13 +167,18 @@ export const Links = ({ Link = false }) => {
{control > 2 && (
-
+
- Import data
-
+ Import data
+
)}
{control > 2 && (
-
+
- Export your data
-
+ Export your data
+
)}
{control > 2 && (
-
+
- Reload account data
-
+ Reload account data
+
)}
{control > 3 && (
-
+
- Restrict processing of your data
-
+ Restrict processing of your data
+
)}
-
+
- Remove your account
-
+ Remove your account
+
)}
diff --git a/packages/react/components/Account/Newsletter.mjs b/packages/react/components/Account/Newsletter.mjs
new file mode 100644
index 00000000000..3d446ca0011
--- /dev/null
+++ b/packages/react/components/Account/Newsletter.mjs
@@ -0,0 +1,139 @@
+// Dependencies
+import { welcomeSteps } from './shared.mjs'
+import { linkClasses } from '@freesewing/utils'
+
+// Context
+import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus'
+
+// Hooks
+import React, { useState, useContext } from 'react'
+import { useAccount } from '@freesewing/react/hooks/useAccount'
+import { useBackend } from '@freesewing/react/hooks/useBackend'
+
+// Components
+import { Link as WebLink } from '@freesewing/react/components/Link'
+import { NoIcon, OkIcon, SaveIcon } from '@freesewing/react/components/Icon'
+import { ListInput } from '@freesewing/react/components/Input'
+import { Popout } from '@freesewing/react/components/Popout'
+
+const strings = {
+ yes: {
+ title: 'Yes, in case it may help me',
+ desc:
+ 'Allowing us to compare your measurments to a baseline or others measurements sets ' +
+ 'allows us to detect potential problems in your measurements or patterns.',
+ },
+ no: {
+ title: 'No, never compare',
+ desc:
+ 'We get it, comparison is the thief of joy. Just be aware that this limits our ability ' +
+ 'to warn you about potential problems in your measurements sets or patterns.',
+ },
+}
+
+/*
+ * Component for the account/preferences/newsletter page
+ *
+ * @params {object} props - All React props
+ * @params {bool} props.welcome - Set to true to use this component on the welcome page
+ * @param {function} props.Link - An optional framework-specific Link component
+ */
+export const Newsletter = ({ welcome = false, Link = false }) => {
+ if (!Link) Link = WebLink
+
+ // Hooks
+ const { account, setAccount } = useAccount()
+ const backend = useBackend()
+ const { setLoadingStatus } = useContext(LoadingStatusContext)
+
+ // State
+ const [selection, setSelection] = useState(account?.newsletter ? 'yes' : 'no')
+
+ // Helper method to update account
+ const update = async (val) => {
+ if (val !== selection) {
+ setLoadingStatus([true, 'Saving preferences'])
+ const [status, body] = await backend.updateAccount({
+ newsletter: val === 'yes' ? true : false,
+ })
+ if (status === 200) {
+ setLoadingStatus([true, 'Preferences saved', true, true])
+ setAccount(body.account)
+ setSelection(val)
+ } else setLoadingStatus([true, 'An error occured. Please report this.', true, true])
+ }
+ }
+
+ // Next step for onboarding
+ const nextHref =
+ welcomeSteps[account?.control].length > 2
+ ? '/welcome/' + welcomeSteps[account?.control][2]
+ : '/docs/about/guide'
+
+ return (
+
+ ({
+ val,
+ label: (
+
+
+ {val === 'yes' ? 'Yes, I would like to receive the newsletter' : 'No thanks'}
+
+ {val === 'yes' ? (
+
+ ) : (
+
+ )}
+
+ ),
+ desc:
+ val === 'yes'
+ ? `Once every 3 months you'll receive an email from us with honest wholesome content. No tracking, no ads, no nonsense.`
+ : `You can always change your mind later. But until you do, we will not send you any newsletters.`,
+ }))}
+ current={selection}
+ update={update}
+ />
+ {welcome ? (
+ <>
+
+ {welcomeSteps[account?.control].length > 0 ? (
+ <>
+
+
+ 2 / {welcomeSteps[account?.control].length}
+
+
+ >
+ ) : null}
+ >
+ ) : null}
+
+
You can unsubscribe at any time with the link below
+
+ This unsubscribe link will also be included at the bottom of every newsletter we send you,
+ so you do not need to bookmark it, but you can if you want to.
+
+
+
+ Unsubscribe link
+
+
+
+ This link is to unsubscribe you specifically, do not share it with other subscribers.
+