1
0
Fork 0

feat: Upgrade to TailwindCSS 4 & DaisyUI 5 (#263)

Also fixes #251

Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/263
Co-authored-by: joostdecock <joost@joost.at>
Co-committed-by: joostdecock <joost@joost.at>
This commit is contained in:
joostdecock 2025-04-18 08:07:13 +00:00 committed by Joost De Cock
parent a2863e5158
commit 44e04a4cef
164 changed files with 2361 additions and 2658 deletions

View file

@ -102,16 +102,16 @@ export const Apikeys = ({ Link = false }) => {
return (
<>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-2 tw-items-center tw-justify-between tw-mb-4">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-2 tw:items-center tw:justify-between tw:mb-4">
<button
className="tw-daisy-btn tw-daisy-btn-error"
className="tw:daisy-btn tw:daisy-btn-error"
onClick={removeSelectedApikeys}
disabled={count < 1}
>
<TrashIcon /> {count} API Keys
</button>
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-capitalize tw-w-full md:tw-w-auto hover:tw-text-primary-content"
className="tw:daisy-btn tw:daisy-btn-primary tw:capitalize tw:w-full tw:md:w-auto tw:hover:text-primary-content"
onClick={() =>
setModal(
<ModalWrapper keepOpenOnClick>
@ -125,13 +125,13 @@ export const Apikeys = ({ Link = false }) => {
</button>
</div>
<TableWrapper>
<table className="tw-table tw-table-auto">
<thead className="tw-border tw-border-base-300 tw-border-b-2 tw-border-t-0 tw-border-x-0">
<table className="tw:table tw:table-auto">
<thead className="tw:border tw:border-base-300 tw:border-b-2 tw:border-t-0 tw:border-x-0">
<tr className="">
<th className="">
<input
type="checkbox"
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={toggleAll}
checked={apikeys.length === count}
/>
@ -139,13 +139,13 @@ export const Apikeys = ({ Link = false }) => {
{Object.keys(fields).map((field) => (
<th key={field}>
<button
className="tw-daisy-btn tw-daisy-btn-link tw-capitalize tw-px-0 underline tw-hover:decoration-4 tw-decoration-2 tw-text-secondary"
className="tw:daisy-btn tw:daisy-btn-link tw:capitalize tw:px-0 underline tw:hover:decoration-4 tw:decoration-2 tw:text-secondary"
onClick={() => (order === field ? setDesc(!desc) : setOrder(field))}
>
{fields[field]}{' '}
<RightIcon
stroke={3}
className={`tw-w-4 tw-h-4 ${desc ? 'tw--' : 'tw-'}rotate-90 ${order === field ? '' : 'tw-opacity-0'}`}
className={`tw:w-4 tw:h-4 ${desc ? 'tw:-' : 'tw:'}rotate-90 ${order === field ? '' : 'tw:opacity-0'}`}
/>
</button>
</th>
@ -155,23 +155,23 @@ export const Apikeys = ({ Link = false }) => {
<tbody>
{orderBy(apikeys, order, desc ? 'desc' : 'asc').map((apikey, i) => (
<tr key={i}>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">
<input
type="checkbox"
checked={selection[apikey.id] ? true : false}
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={() => toggle(apikey.id)}
/>
</td>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">
<Uuid uuid={apikey.id} label="Key" />
</td>
{Object.keys(fields)
.slice(1, 4)
.map((field) => (
<td key={field} className="tw-text-base tw-font-medium">
<td key={field} className="tw:text-base tw:font-medium">
<button
className="tw-daisy-btn tw-daisy-btn-link tw-text-secondary hover:tw-decoration-4"
className="tw:daisy-btn tw:daisy-btn-link tw:text-secondary tw:hover:decoration-4"
onClick={() =>
setModal(
<ModalWrapper>
@ -184,8 +184,8 @@ export const Apikeys = ({ Link = false }) => {
</button>
</td>
))}
<td className="tw-text-base tw-font-medium">{shortDate(apikey.createdAt)}</td>
<td className="tw-text-base tw-font-medium">{shortDate(apikey.expiresAt)}</td>
<td className="tw:text-base tw:font-medium">{shortDate(apikey.createdAt)}</td>
<td className="tw:text-base tw:font-medium">{shortDate(apikey.expiresAt)}</td>
</tr>
))}
</tbody>
@ -197,10 +197,10 @@ export const Apikeys = ({ Link = false }) => {
const ApiKey = ({ apikey }) => (
<>
<h2 className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<h2 className="tw:flex tw:flex-row tw:items-center tw:gap-2">
API Key <Uuid uuid={apikey.id} />
</h2>
<ul className="tw-list tw-list-disc tw-ml-4">
<ul className="tw:list tw:list-disc tw:ml-4">
{Object.entries(fields).map(([key, label]) => (
<li key={key}>
{label}: <b>{apikey[key]}</b>
@ -248,7 +248,7 @@ const NewApikey = ({ onCreate = false }) => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<h2>New API key {apikey ? `: ${apikey.name}` : ''}</h2>
{apikey ? (
<ShowNewApikey {...{ apikey }} />
@ -269,7 +269,7 @@ const NewApikey = ({ onCreate = false }) => {
list={levels.map((l) => ({
val: l,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-w-full tw-justify-between">
<div className="tw:flex tw:flex-row tw:items-center tw:w-full tw:justify-between">
<span>{apikeyLevels[l]}</span>
<NumberCircle nr={l} color="secondary" />
</div>
@ -278,9 +278,9 @@ const NewApikey = ({ onCreate = false }) => {
current={level}
update={setLevel}
/>
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-w-full tw-my-8">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:w-full tw:my-8">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-capitalize tw-w-full md:tw-w-auto"
className="tw:daisy-btn tw:daisy-btn-primary tw:capitalize tw:w-full tw:md:w-auto"
disabled={name.length < 1}
onClick={createKey}
>
@ -295,18 +295,18 @@ const NewApikey = ({ onCreate = false }) => {
const ShowNewApikey = ({ apikey }) => (
<div>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-2 tw-items-center tw-mb-2">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-2 tw:items-center tw:mb-2">
<KeyVal k="name" val={apikey.name} color="secondary" />
<KeyVal k="level" val={apikey.level} color="secondary" />
<KeyVal k="created" val={<TimeAgo iso={apikey.createdAt} />} color="secondary" />
<KeyVal k="expires" val={<TimeToGo iso={apikey.expiresAt} />} color="secondary" />
</div>
<h6 className="tw-flex tw-flex-row tw-items-center">
<h6 className="tw:flex tw:flex-row tw:items-center">
Key
<CopyToClipboardButton sup content={apikey.key} label="API key ID" />
</h6>
<pre>{apikey.key}</pre>
<h6 className="tw-flex tw-flex-row tw-items-center">
<h6 className="tw:flex tw:flex-row tw:items-center">
Secret
<CopyToClipboardButton sup content={apikey.secret} label="API key secret" />
</h6>
@ -330,7 +330,7 @@ const ExpiryPicker = ({ expires, setExpires }) => {
}
return (
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center">
<FormControl
label="Key Expiry"
labelBL={shortDate(expires)}
@ -341,7 +341,7 @@ const ExpiryPicker = ({ expires, setExpires }) => {
min="1"
max={731}
value={days}
className="tw-daisy-range tw-daisy-range-secondary tw-w-full"
className="tw:daisy-range tw:daisy-range-secondary tw:w-full"
onChange={update}
/>
</FormControl>

View file

@ -51,12 +51,12 @@ export const Avatar = ({ welcome = false, Link = false }) => {
const nextHref = '/docs/about/guide'
return (
<div className="tw-w-full">
<div className="tw:w-full">
{!welcome || img !== false ? (
<img
alt="img"
src={img || cloudflareImageUrl({ id: `uid-${account.ihash}`, variant: 'public' })}
className="tw-shadow tw-mb-4"
className="tw:shadow tw:mb-4"
/>
) : null}
<PassiveImageInput
@ -73,17 +73,17 @@ export const Avatar = ({ welcome = false, Link = false }) => {
<SaveIcon />
Save
</IconButton>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[account.control].length > 0 ? (
<>
<progress
className="tw-progress tw-progress-primary tw-w-full tw-mt-12"
className="tw:progress tw:progress-primary tw:w-full tw:mt-12"
value={700 / welcomeSteps[account.control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
7 / {welcomeSteps[account.control].length}
</span>
<WelcomeIcons
@ -96,9 +96,9 @@ export const Avatar = ({ welcome = false, Link = false }) => {
</>
) : (
<>
<p className="tw-text-right">
<p className="tw:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto mt-8"
onClick={save}
>
<SaveIcon /> Save Avatar

View file

@ -51,12 +51,12 @@ export const Bio = ({ welcome = false, Link = false }) => {
: '/docs/about/guide'
return (
<div className="tw-w-full">
<div className="tw:w-full">
<h6>Tell people a little bit about yourself.</h6>
<MarkdownInput id="account-bio" label="Bio" update={setBio} current={bio} placeholder="Bio" />
<p className="tw-text-right">
<p className="tw:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto tw:mt-8"
onClick={save}
>
<SaveIcon /> Save Bio
@ -65,17 +65,17 @@ export const Bio = ({ welcome = false, Link = false }) => {
{welcome ? (
<>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[account.control].length > 0 ? (
<>
<progress
className="tw-daisy-progress tw-daisy-progress-primary tw-w-full tw-mt-12"
className="tw:daisy-progress tw:daisy-progress-primary tw:w-full tw:mt-12"
value={600 / welcomeSteps[account.control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
6 / {welcomeSteps[account.control].length}
</span>
<WelcomeIcons

View file

@ -88,10 +88,10 @@ export const Bookmarks = () => {
for (const type in types) perType[type] = bookmarks.filter((b) => b.type === type)
return (
<div className="tw-w-full">
<p className="tw-text-center md:tw-text-right">
<div className="tw:w-full">
<p className="tw:text-center tw:md:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-capitalize tw-w-full md:tw-w-auto hover:tw-text-primary-content hover:tw-no-underline"
className="tw:daisy-btn tw:daisy-btn-primary tw:capitalize tw:w-full tw:md:w-auto tw:hover:text-primary-content tw:hover:no-underline"
onClick={() =>
setModal(
<ModalWrapper
@ -100,7 +100,7 @@ export const Bookmarks = () => {
slideFrom="right"
keepOpenOnClick
>
<div className="tw-w-full">
<div className="tw:w-full">
<h2>New Bookmark</h2>
<NewBookmark onCreated={() => setRefresh(refresh + 1)} />
</div>
@ -114,7 +114,7 @@ export const Bookmarks = () => {
</p>
{bookmarks.length > 0 ? (
<button
className="tw-daisy-btn tw-daisy-btn-error"
className="tw:daisy-btn tw:daisy-btn-error"
onClick={removeSelectedBookmarks}
disabled={selCount < 1}
>
@ -125,18 +125,18 @@ export const Bookmarks = () => {
perType[type].length > 0 ? (
<Fragment key={type}>
<h2>{title}</h2>
<table className="tw-table tw-w-full">
<thead className="tw-border tw-border-base-300 tw-border-b-2 tw-border-t-0 tw-border-x-0">
<table className="tw:table tw:w-full">
<thead className="tw:border tw:border-base-300 tw:border-b-2 tw:border-t-0 tw:border-x-0">
<tr>
<th className="tw-text-base-300 tw-text-base tw-text-left tw-w-8">
<th className="tw:text-base-300 tw:text-base tw:text-left tw:w-8">
<input
type="checkbox"
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={toggleSelectAll}
checked={bookmarks.length === selCount}
/>
</th>
<th className="tw-w-1/2">Title</th>
<th className="tw:w-1/2">Title</th>
<th>Location</th>
</tr>
</thead>
@ -145,16 +145,16 @@ export const Bookmarks = () => {
.filter((bookmark) => bookmark.type === type)
.map((bookmark, i) => (
<tr key={i}>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">
<input
type="checkbox"
checked={selected[bookmark.id] ? true : false}
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={() => toggleSelect(bookmark.id)}
/>
</td>
<td className="tw-text-base tw-font-medium">{bookmark.title}</td>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">{bookmark.title}</td>
<td className="tw:text-base tw:font-medium">
<WebLink href={bookmark.url}>
{bookmark.url.length > 30
? bookmark.url.slice(0, 30) + '...'
@ -210,7 +210,7 @@ export const NewBookmark = ({ onCreated = false }) => {
// Render the form
return (
<div className="tw-w-full">
<div className="tw:w-full">
<StringInput
id="bookmark-title"
label="Title"
@ -229,9 +229,9 @@ export const NewBookmark = ({ onCreated = false }) => {
valid={(val) => val.length > 0}
placeholder={'https://freesewing.org/account'}
/>
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-w-full tw-my-8">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:w-full tw:my-8">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-grow tw-capitalize"
className="tw:daisy-btn tw:daisy-btn-primary tw:grow tw:capitalize"
disabled={!(title.length > 0 && url.length > 0)}
onClick={createBookmark}
>
@ -256,7 +256,7 @@ export const BookmarkButton = ({ slug, type, title }) => {
return (
<button
className={`tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline ${horFlexClasses}`}
onClick={() =>
setModal(
<ModalWrapper flex="col" justify="top lg:justify-center" slideFrom="right">
@ -305,10 +305,10 @@ export const CreateBookmark = ({ type, title, slug }) => {
}
return (
<div className="tw-mt-12">
<div className="tw:mt-12">
<h2>New bookmark</h2>
<StringInput label="Title" current={name} update={setName} valid={notEmpty} labelBL={url} />
<button className="tw-daisy-btn tw-daisy-btn-primary tw-w-full tw-mt-4" onClick={bookmark}>
<button className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:mt-4" onClick={bookmark}>
Create bookmark
</button>
</div>

View file

@ -70,19 +70,19 @@ export const Compare = ({ welcome = false }) => {
: '/docs/about/guide'
return (
<div className="tw-w-full">
<div className="tw:w-full">
<ListInput
id="account-compare"
label="Are you comfortable with your measurements sets being compared?"
list={['yes', 'no'].map((val) => ({
val,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-w-full tw-justify-between">
<div className="tw:flex tw:flex-row tw:items-center tw:w-full tw:justify-between">
<span>{strings[val].title}</span>
{val === 'yes' ? (
<OkIcon className="tw-w-8 h-8 tw-text-success" stroke={4} />
<OkIcon className="tw:w-8 h-8 tw:text-success" stroke={4} />
) : (
<NoIcon className="tw-w-8 h-8 tw-text-error" stroke={3} />
<NoIcon className="tw:w-8 h-8 tw:text-error" stroke={3} />
)}
</div>
),
@ -93,17 +93,17 @@ export const Compare = ({ welcome = false }) => {
/>
{welcome ? (
<>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[account?.control].length > 0 ? (
<>
<progress
className="tw-daisy-progress tw-daisy-progress-primary tw-w-full tw-mt-12"
className="tw:daisy-progress tw:daisy-progress-primary tw:w-full tw:mt-12"
value={400 / welcomeSteps[account?.control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
4 / {welcomeSteps[account?.control].length}
</span>
<WelcomeIcons

View file

@ -86,16 +86,16 @@ export const Consent = ({ signUp = false, Link = false, title = false }) => {
}
return (
<div className="tw-w-full mdx">
{title ? <h2 className="tw-text-4xl">Privacy Matters</h2> : null}
<div className="tw:w-full mdx">
{title ? <h2 className="tw:text-4xl">Privacy Matters</h2> : null}
{text.intro}
<h5 className="tw-mt-8">Do you give your consent to process your account data?</h5>
<h5 className="tw:mt-8">Do you give your consent to process your account data?</h5>
{text.account}
{consent1 ? (
<Checkbox value={consent1} setter={setConsent1} label="Yes, I do" />
) : (
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-lg tw-w-full tw-mt-4"
className="tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-lg tw:w-full tw:mt-4"
onClick={() => setConsent1(!consent1)}
>
Click here to give your consent
@ -103,7 +103,7 @@ export const Consent = ({ signUp = false, Link = false, title = false }) => {
)}
{consent1 ? (
<>
<h5 className="tw-mt-8">
<h5 className="tw:mt-8">
Do you give your consent to share your anonymized measurements
</h5>
<Checkbox
@ -116,19 +116,19 @@ export const Consent = ({ signUp = false, Link = false, title = false }) => {
) : null}
{!consent1 && <Popout warning>This consent is required for a FreeSewing account.</Popout>}
{consent1 ? (
<button className="tw-daisy-btn tw-daisy-btn-primary tw-w-full tw-mt-4" onClick={update}>
<button className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:mt-4" onClick={update}>
{signUp ? 'Create Account' : 'Save'}
</button>
) : signUp ? null : (
<button
className="tw-daisy-btn tw-mt-4 tw-capitalize tw-w-full tw-daisy-btn-error"
className="tw:daisy-btn tw:mt-4 tw:capitalize tw:w-full tw:daisy-btn-error"
onClick={removeAccount}
>
Remove your account
</button>
)}
<p className="tw-text-center tw-opacity-50 tw-mt-12">
<Link href="/docs/about/privacy" className="hover:tw-text-secondary tw-underline">
<p className="tw:text-center tw:opacity-50 tw:mt-12">
<Link href="/docs/about/privacy" className="tw:hover:text-secondary tw:underline">
FreeSewing Privacy Notice
</Link>
</p>
@ -138,19 +138,19 @@ export const Consent = ({ signUp = false, Link = false, title = false }) => {
const Checkbox = ({ value, setter, label, children = null }) => (
<div
className={`tw-form-control tw-p-4 hover:tw-cursor-pointer tw-rounded tw-border-l-8 tw-my-2
${value ? 'tw-border-success tw-bg-success/30' : 'tw-border-error tw-bg-error/30'}
btw-g-opacity-10 tw-shadow`}
className={`tw:form-control tw:p-4 tw:hover:cursor-pointer tw:rounded tw:border-l-8 tw:my-2
${value ? 'tw:border-success tw:bg-success/30' : 'tw:border-error tw:bg-error/30'}
btw:g-opacity-10 tw:shadow`}
onClick={() => setter(value ? false : true)}
>
<div className="tw-form-control tw-flex tw-flex-row tw-items-center tw-gap-2">
<div className="tw:form-control tw:flex tw:flex-row tw:items-center tw:gap-2">
<input
type="checkbox"
className="tw-daisy-checkbox"
className="tw:daisy-checkbox"
checked={value ? 'checked' : ''}
onChange={() => setter(value ? false : true)}
/>
<span className="tw-label-text">{label}</span>
<span className="tw:label-text">{label}</span>
</div>
{children}
</div>
@ -174,7 +174,7 @@ const text = {
</>
),
account: (
<div className="tw-border-l-4 tw-ml-1 tw-pl-4 tw-my-2 tw-opacity-80">
<div className="tw:border-l-4 tw:ml-1 tw:pl-4 tw:my-2 tw:opacity-80">
<h6>What is account data?</h6>
<p>
Your <b>email address</b>, <b>username</b>, and <b>password</b>, and any <b>measurements</b>{' '}
@ -194,7 +194,7 @@ const text = {
<p>
<b>No</b>, never.
</p>
<p className="tw-text-sm tw-italic">
<p className="tw:text-sm tw:italic">
Note: Freesewing publishes anonymized measurements as open data for scientific research. You
have the right to object to this.
</p>

View file

@ -52,14 +52,14 @@ export const Control = ({ welcome = false }) => {
: false
return (
<div className="tw-w-full">
<div className="tw:w-full">
<ListInput
id="account-control"
label="What user experience do you prefer?"
list={[1, 2, 3, 4, 5].map((val) => ({
val,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-w-full tw-justify-between">
<div className="tw:flex tw:flex-row tw:items-center tw:w-full tw:justify-between">
<span>{controlDesc[val].title}</span>
<ControlScore control={val} />
</div>
@ -71,17 +71,17 @@ export const Control = ({ welcome = false }) => {
/>
{welcome ? (
<>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[control].length > 1 ? (
<>
<progress
className="tw-daisy-progress tw-daisy-progress-primary tw-w-full tw-mt-12"
className="tw:daisy-progress tw:daisy-progress-primary tw:w-full tw:mt-12"
value={100 / welcomeSteps[control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
1 / {welcomeSteps[control].length}
</span>
<WelcomeIcons done={[]} todo={welcomeSteps[control].slice(1)} current="" />

View file

@ -51,7 +51,7 @@ export const Email = ({ welcome = false, Link = false }) => {
const valid = (validateEmail(email) && validateTld(email)) || false
return (
<div className="tw-w-full">
<div className="tw:w-full">
{changed ? (
<Popout note>
<h3>Please confirm this change</h3>
@ -72,9 +72,9 @@ export const Email = ({ welcome = false, Link = false }) => {
original={account.email}
valid={() => valid}
/>
<p className="tw-text-right">
<p className="tw:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto tw:mt-8"
onClick={save}
disabled={!valid || email.toLowerCase() === account.email}
>
@ -151,7 +151,7 @@ export const EmailChangeConfirmation = ({ onSuccess = false }) => {
return (
<>
<h1>One moment pleae</h1>
<Spinner className="tw-w-8 tw-h-8 tw-m-auto tw-animate-spin" />
<Spinner className="tw:w-8 tw:h-8 tw:m-auto tw:animate-spin" />
</>
)

View file

@ -34,11 +34,11 @@ export const Export = () => {
}
return (
<div className="tw-max-w-xl">
<div className="tw:max-w-xl">
{link ? (
<Popout link>
<h5>Your data was exported and is available for download at the following location:</h5>
<p className="tw-text-lg">
<p className="tw:text-lg">
<WebLink href={link}>{link}</WebLink>
</p>
</Popout>

View file

@ -34,7 +34,7 @@ export const Github = () => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<StringInput
id="account-github-email"
label="GitHub Email Address"
@ -51,9 +51,9 @@ export const Github = () => {
valid={(val) => val.length > 0}
placeholder={'joostdecock'}
/>
<p className="tw-text-right">
<p className="tw:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto tw:mt-8"
onClick={save}
>
<SaveIcon /> Save

View file

@ -62,7 +62,7 @@ export const ImportSet = () => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<FileInput
label="Measurements file (YAML / JSON)"
update={uploadSet}

View file

@ -34,7 +34,7 @@ export const Instagram = () => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<StringInput
id="account-github-email"
label="GitHub Email Address"
@ -51,9 +51,9 @@ export const Instagram = () => {
valid={(val) => val.length > 0}
placeholder={'joostdecock'}
/>
<p className="tw-text-right">
<p className="tw:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto tw:mt-8"
onClick={save}
>
<SaveIcon /> Save

View file

@ -72,10 +72,10 @@ const itemIcons = {
reddit: <RedditIcon />,
}
const btnClasses = 'tw-daisy-btn tw-capitalize tw-flex tw-flex-row tw-justify-between'
const btnClasses = 'tw:daisy-btn tw:capitalize tw:flex tw:flex-row tw:justify-between'
const itemClasses =
'tw-flex tw-flex-row tw-items-center tw-justify-between tw-bg-opacity-10 tw-p-2 tw-px-4 tw-rounded tw-mb-1'
const linkClasses = `hover:tw-bg-secondary hover:tw-bg-opacity-10 tw-max-w-md hover:tw-no-underline`
'tw:flex tw:flex-row tw:items-center tw:justify-between tw:p-2 tw:px-4 tw:rounded tw:mb-1'
const linkClasses = `tw:hover:bg-secondary/10 tw:max-w-md tw:hover:no-underline tw:text-base-content no-hover-decoration`
const titles = {
apikeys: 'API Keys',
@ -142,7 +142,7 @@ export const Links = ({ Link = false }) => {
img: (
<img
src={cloudflareImageUrl({ type: 'sq100', id: `uid-${account.ihash}` })}
className="tw-w-8 tw-h-8 tw-aspect-square tw-rounded-full shadow"
className="tw:w-8 tw:h-8 tw:aspect-square tw:rounded-full shadow"
/>
),
units: account.imperial ? 'Imperial' : 'Metric',
@ -158,14 +158,14 @@ export const Links = ({ Link = false }) => {
(i) => i !== 'github'
))
itemPreviews[social] = account.data[social] || (
<NoIcon className="tw-text-base-content tw-w-6 tw-h-6" stroke={2} />
<NoIcon className="tw:text-base-content tw:w-6 tw:h-6" stroke={2} />
)
return (
<div className="tw-w-full">
<div className="tw-grid tw-grid-cols-1 xl:tw-grid-cols-2 tw-gap-4 tw-mb-8">
<div className="tw:w-full">
<div className="tw:grid tw:grid-cols-1 tw:xl:grid-cols-2 tw:gap-4 tw:mb-8">
<div>
<h4 className="tw-my-2">Your Data</h4>
<h4 className="tw:my-2">Your Data</h4>
{Object.keys(controlConfig.account.fields.data).map((item) =>
controlConfig.flat[item] > control ? null : (
<Link
@ -174,11 +174,11 @@ export const Links = ({ Link = false }) => {
href={`/account/data/${item}/`}
className={`${itemClasses} ${linkClasses}`}
>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium tw:text-base-content">
{itemIcons[item]}
{titles[item] ? titles[item] : capitalize(item)}
</div>
<div>{itemPreviews[item]}</div>
<div className="tw:text-base-content">{itemPreviews[item]}</div>
</Link>
)
)}
@ -186,7 +186,7 @@ export const Links = ({ Link = false }) => {
{control > 1 && (
<div>
<h4 className="tw-my-2">About You</h4>
<h4 className="tw:my-2">About You</h4>
{Object.keys(controlConfig.account.fields.info).map((item) =>
controlConfig.flat[item] > control ? null : (
<Link
@ -195,23 +195,23 @@ export const Links = ({ Link = false }) => {
href={`/account/about/${item === 'img' ? 'avatar' : item}/`}
className={`${itemClasses} ${linkClasses}`}
>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium tw:text-base-content">
{itemIcons[item]}
{titles[item] ? titles[item] : capitalize(item)}
</div>
<div>{itemPreviews[item]}</div>
<div className="tw:text-base-content">{itemPreviews[item]}</div>
</Link>
)
)}
<div className={`${itemClasses} tw-opacity-60 tw-max-w-md`}>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className={`${itemClasses} tw:opacity-60 tw:max-w-md`}>
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium">
<OkIcon stroke={3} />
<span>Role</span>
</div>
<div className="tw-capitalize">{account.role}</div>
<div className="tw:capitalize">{account.role}</div>
</div>
<div className={`${itemClasses} tw-opacity-60 tw-max-w-md`}>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className={`${itemClasses} tw:opacity-60 tw:max-w-md`}>
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium">
<FingerprintIcon />
<span>ID</span>
</div>
@ -221,7 +221,7 @@ export const Links = ({ Link = false }) => {
)}
<div>
<h4 className="tw-my-2">Preferences</h4>
<h4 className="tw:my-2">Preferences</h4>
{Object.keys(controlConfig.account.fields.settings).map((item) =>
controlConfig.flat[item] > control ? null : (
<Link
@ -230,11 +230,11 @@ export const Links = ({ Link = false }) => {
href={`/account/preferences/${item}/`}
className={`${itemClasses} ${linkClasses}`}
>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium tw:text-base-content">
{itemIcons[item]}
{titles[item] ? titles[item] : capitalize(item)}
</div>
<div>{itemPreviews[item]}</div>
<div className="tw:text-base-content">{itemPreviews[item]}</div>
</Link>
)
)}
@ -242,7 +242,7 @@ export const Links = ({ Link = false }) => {
{control > 2 && (
<div>
<h4 className="tw-my-2">Linked Identities</h4>
<h4 className="tw:my-2">Linked Identities</h4>
{Object.keys(controlConfig.account.fields.identities).map((item) =>
controlConfig.flat[item] > control ? null : (
<Link
@ -251,11 +251,11 @@ export const Links = ({ Link = false }) => {
href={`/account/social/${item}/`}
className={`${itemClasses} ${linkClasses}`}
>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium tw:text-base-content">
{itemIcons[item]}
{titles[item] ? titles[item] : capitalize(item)}
</div>
<div>{itemPreviews[item]}</div>
<div className="tw:text-base-content">{itemPreviews[item]}</div>
</Link>
)
)}
@ -264,7 +264,7 @@ export const Links = ({ Link = false }) => {
{control > 1 && (
<div>
<h4 className="tw-my-2">Security</h4>
<h4 className="tw:my-2">Security</h4>
{Object.keys(controlConfig.account.fields.security).map((item) =>
controlConfig.flat[item] > control ? null : (
<Link
@ -273,11 +273,11 @@ export const Links = ({ Link = false }) => {
href={`/account/security/${item}/`}
className={`${itemClasses} ${linkClasses}`}
>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium tw:text-base-content">
{itemIcons[item]}
{titles[item] ? titles[item] : capitalize(item)}
</div>
<div>{itemPreviews[item]}</div>
<div className="tw:text-base-content">{itemPreviews[item]}</div>
</Link>
)
)}
@ -286,15 +286,15 @@ export const Links = ({ Link = false }) => {
{control > 1 && (
<div>
<h4 className="tw-my-2">Actions</h4>
<h4 className="tw:my-2">Actions</h4>
{control > 2 && (
<Link
className={`${itemClasses} ${linkClasses}`}
title="Import data"
href="/account/actions/import/"
>
<UploadIcon />
<span className="tw-font-medium">Import data</span>
<UploadIcon className="tw:w-6 tw:h-6 tw:text-base-content" />
<span className="tw:font-medium tw:text-base-content">Import data</span>
</Link>
)}
{control > 2 && (
@ -303,8 +303,8 @@ export const Links = ({ Link = false }) => {
title="Export your data"
href="/account/actions/export/"
>
<DownloadIcon />
<span className="tw-font-medium">Export your data</span>
<DownloadIcon className="tw:w-6 tw:h-6 tw:text-base-content" />
<span className="tw:font-medium tw:text-base-content">Export your data</span>
</Link>
)}
{control > 2 && (
@ -313,8 +313,8 @@ export const Links = ({ Link = false }) => {
title="Reload account data"
href="/account/actions/reload/"
>
<ReloadIcon />
<span className="tw-font-medium">Reload account data</span>
<ReloadIcon className="tw:w-6 tw:h-6 tw:text-base-content" />
<span className="tw:font-medium tw:text-base-content">Reload account data</span>
</Link>
)}
{control > 3 && (
@ -323,8 +323,10 @@ export const Links = ({ Link = false }) => {
title="Restrict processing of your data"
href="/account/actions/restrict/"
>
<CloseIcon className="tw-w-6 tw-h-6 tw-text-warning" stroke={3} />
<span className="tw-font-medium">Restrict processing of your data</span>
<CloseIcon className="tw:w-6 tw:h-6 tw:text-warning" stroke={3} />
<span className="tw:font-medium tw:text-base-content">
Restrict processing of your data
</span>
</Link>
)}
<Link
@ -332,28 +334,31 @@ export const Links = ({ Link = false }) => {
title="Remove your account"
href="/account/actions/remove/"
>
<TrashIcon className="tw-w-6 tw-h-6 tw-text-warning" />
<span className="tw-font-medium">Remove your account</span>
<TrashIcon className="tw:w-6 tw:h-6 tw:text-warning" />
<span className="tw:font-medium tw:text-base-content">Remove your account</span>
</Link>
</div>
)}
</div>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-2 md:tw-gap-4 tw-justify-end">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-2 tw:md:gap-4 tw:justify-end">
{account.role === 'admin' && (
<Link className={`${btnClasses} tw-daisy-btn-accent md:tw-w-64`} href="/admin">
<WrenchIcon />
Administration
<Link
className={`${btnClasses} tw:daisy-btn-accent tw:md:w-64 tw:text-accent-content`}
href="/admin"
>
<WrenchIcon className="tw:w-6 tw:h-6 tw:text-accent-content" />
<span className="tw:text-accent-content">Administration</span>
</Link>
)}
{control > 1 && (
<Link className={`${btnClasses} tw-daisy-btn-secondary md:tw-w-64`} href="/profile">
<UserIcon />
Your Profile
<Link className={`${btnClasses} tw:daisy-btn-secondary tw:md:w-64`} href="/profile">
<UserIcon className="tw:w-6 tw:h-6 tw:text-accent-content" />
<span className="tw:text-accent-content">Your Profile</span>
</Link>
)}
<button
className={`${btnClasses} tw-daisy-btn-neutral md:tw-w-64`}
className={`${btnClasses} tw:daisy-btn-neutral tw:md:w-64`}
onClick={() => signOut()}
>
<SignoutIcon />

View file

@ -89,14 +89,14 @@ export const Mfa = ({ welcome = false, title = true }) => {
if (enable) titleText = 'Set up Multi-Factor Authentication'
return (
<div className="tw-w-full">
<div className="tw:w-full">
{title ? <h2>{titleText}</h2> : null}
{enable ? (
<>
<div className="tw-flex tw-flex-row tw-items-center tw-justify-center tw-px-8 lg:tw-px-36">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-center tw:px-8 tw:lg:px-36">
<div dangerouslySetInnerHTML={{ __html: enable.qrcode }} />
</div>
<p className="tw-flex tw-flex-row tw-items-center tw-justify-center">{enable.secret}</p>
<p className="tw:flex tw:flex-row tw:items-center tw:justify-center">{enable.secret}</p>
<Bullet num="1">
Add FreeSewing to your Authenticator App by scanning the QR code above. If you cannot
scan the QR code, you can manually enter the secret below it.
@ -107,14 +107,14 @@ export const Mfa = ({ welcome = false, title = true }) => {
<input
value={code}
onChange={(evt) => setCode(evt.target.value)}
className="tw-daisy-input tw-w-64 tw-m-auto tw-text-4xl tw-daisy-input-bordered tw-daisy-input-lg tw-flex tw-flex-row tw-text-center tw-mb-8 tw-tracking-widest"
className="tw:daisy-input tw:w-64 tw:m-auto tw:text-4xl tw:daisy-input-bordered tw:daisy-input-lg tw:flex tw:flex-row tw:text-center tw:mb-8 tw:tracking-widest"
type="text"
inputMode="numeric"
pattern="[0-9]{6}"
placeholder="000000"
/>
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-success tw-daisy-btn-lg tw-block tw-w-full md:tw-w-auto tw-mx-auto`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-success tw:daisy-btn-lg tw:block tw:w-full tw:md:w-auto tw:mx-auto`}
onClick={confirmMfa}
>
<LockIcon />
@ -123,7 +123,7 @@ export const Mfa = ({ welcome = false, title = true }) => {
</>
) : null}
{disable ? (
<div className="tw-my-8 tw-max-w-xl">
<div className="tw:my-8 tw:max-w-xl">
<Bullet num="1">
<h5>Please enter your password to confirm this action</h5>
<PasswordInput
@ -138,13 +138,13 @@ export const Mfa = ({ welcome = false, title = true }) => {
<input
value={code}
onChange={(evt) => setCode(evt.target.value)}
className="tw-input tw-w-full tw-text-4xl tw-input-bordered tw-input-lg tw-flex tw-flex-row tw-text-center tw-mb-8 tw-tracking-widest"
className="tw:input tw:w-full tw:text-4xl tw:input-bordered tw:input-lg tw:flex tw:flex-row tw:text-center tw:mb-8 tw:tracking-widest"
type="text"
placeholder={'000000'}
/>
</Bullet>
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-error tw-daisy-btn-lg`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-error tw:daisy-btn-lg`}
onClick={disableMfa}
disabled={code.length < 4 || password.length < 3}
>
@ -163,8 +163,8 @@ export const Mfa = ({ welcome = false, title = true }) => {
You can use each of these codes only once. Write them down, because this is the only
time you will get to see them.
</p>
<div className="hljs tw-my-4">
<div className="tw-flex tw-flex-row tw-justify-between tw-items-center tw-text-xs tw-font-medium tw-text-warning tw-mt-1 tw-border-b tw-border-neutral-content tw-border-opacity-25 tw-px-4 tw-py-1 tw-mb-2 lg:tw-text-sm">
<div className="hljs tw:my-4">
<div className="tw:flex tw:flex-row tw:justify-between tw:items-center tw:text-xs tw:font-medium tw:text-warning tw:mt-1 tw:border-b tw:border-neutral-content tw:border-opacity-25 tw:px-4 tw:py-1 tw:mb-2 tw:lg:text-sm">
<span>MFA Scratch Codes</span>
<CopyToClipboardButton
content={
@ -173,17 +173,17 @@ export const Mfa = ({ welcome = false, title = true }) => {
}
/>
</div>
<pre className="language-shell hljs tw-text-base lg:tw-text-lg tw-whitespace-break-spaces tw-overflow-scroll tw-pr-4">
<pre className="language-shell hljs tw:text-base tw:lg:text-lg tw:whitespace-break-spaces tw:overflow-scroll tw:pr-4">
{scratchCodes.map((code) => code + '\n')}
</pre>
</div>
</>
) : (
<div className="tw-mt-4">
<div className="tw:mt-4">
{account.mfaEnabled ? (
disable ? null : (
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-primary tw-w-full md:tw-w-auto tw-daisy-btn-outline`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:md:w-auto tw:daisy-btn-outline`}
onClick={() => setDisable(true)}
>
<NoIcon stroke={3} />
@ -193,7 +193,7 @@ export const Mfa = ({ welcome = false, title = true }) => {
) : enable ? null : (
<div>
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-primary tw-w-full md:tw-w-auto tw-daisy-btn-lg`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:md:w-auto tw:daisy-btn-lg`}
onClick={enableMfa}
>
<LockIcon />
@ -215,10 +215,10 @@ export const Mfa = ({ welcome = false, title = true }) => {
}
const Bullet = ({ num, children }) => (
<div className="tw-flex tw-flex-row tw-items-start tw-py-4 tw-w-full tw-gap-4">
<span className="tw-bg-secondary tw-text-secondary-content tw-rounded-full tw-w-8 tw-h-8 tw-p-1 tw-inline-block tw-text-center tw-font-bold tw-mr-4 tw-shrink-0">
<div className="tw:flex tw:flex-row tw:items-start tw:py-4 tw:w-full tw:gap-4">
<span className="tw:bg-secondary tw:text-secondary-content tw:rounded-full tw:w-8 tw:h-8 tw:p-1 tw:inline-block tw:text-center tw:font-bold tw:mr-4 tw:shrink-0">
{num}
</span>
<div className="tw-text-lg tw-grow">{children}</div>
<div className="tw:text-lg tw:grow">{children}</div>
</div>
)

View file

@ -58,21 +58,21 @@ export const Newsletter = ({ welcome = false, Link = false }) => {
: '/docs/about/guide'
return (
<div className="tw-w-full">
<div className="tw:w-full">
<ListInput
id="account-newsletter"
label="Would you like to receive the FreeSewing newsletter?"
list={['yes', 'no'].map((val) => ({
val,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-w-full tw-justify-between">
<div className="tw:flex tw:flex-row tw:items-center tw:w-full tw:justify-between">
<span>
{val === 'yes' ? 'Yes, I would like to receive the newsletter' : 'No thanks'}
</span>
{val === 'yes' ? (
<OkIcon className="tw-w-8 tw-h-8 tw-text-success" stroke={4} />
<OkIcon className="tw:w-8 tw:h-8 tw:text-success" stroke={4} />
) : (
<NoIcon className="tw-w-8 tw-h-8 tw-text-error" stroke={3} />
<NoIcon className="tw:w-8 tw:h-8 tw:text-error" stroke={3} />
)}
</div>
),
@ -86,17 +86,17 @@ export const Newsletter = ({ welcome = false, Link = false }) => {
/>
{welcome ? (
<>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[account?.control].length > 0 ? (
<>
<progress
className="tw-daisy-progress tw-daisy-progress-primary tw-w-full tw-mt-12"
className="tw:daisy-progress tw:daisy-progress-primary tw:w-full tw:mt-12"
value={200 / welcomeSteps[account?.control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
2 / {welcomeSteps[account?.control].length}
</span>
<WelcomeIcons
@ -120,7 +120,7 @@ export const Newsletter = ({ welcome = false, Link = false }) => {
Unsubscribe link
</Link>
</p>
<p className="tw-text-sm">
<p className="tw:text-sm">
This link is to unsubscribe you specifically, do not share it with other subscribers.
</p>
</Popout>

View file

@ -43,7 +43,7 @@ export const Password = ({ welcome = false, Link = false }) => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<PasswordInput
id="account-password"
label="Something only you know"
@ -53,7 +53,7 @@ export const Password = ({ welcome = false, Link = false }) => {
placeholder="Tip: use a password manager"
/>
<button
className={`tw-flex tw-flex-row tw-gap-2 tw-items-center tw-daisy-btn tw-justify-between tw-daisy-btn-primary tw-w-full md:tw-w-auto tw-w-full`}
className={`tw:flex tw:flex-row tw:gap-2 tw:items-center tw:daisy-btn tw:justify-between tw:daisy-btn-primary tw:w-full tw:md:w-auto tw:w-full`}
onClick={save}
disabled={password.length < 4}
>
@ -66,9 +66,9 @@ export const Password = ({ welcome = false, Link = false }) => {
We do not enforce a password policy, but we do recommend you enable Two-Factor
Authentication to keep your FreeSewing account safe.
</p>
<p className="tw-text-right tw-m-0 tw-pt-0">
<Link className="tw-daisy-btn tw-daisy-btn-accent" href="/account/mfa">
Two-Factor Authentication <RightIcon className="tw-h-6 tw-w-6 tw-ml-2" />
<p className="tw:text-right tw:m-0 tw:pt-0">
<Link className="tw:daisy-btn tw:daisy-btn-accent" href="/account/mfa">
Two-Factor Authentication <RightIcon className="tw:h-6 tw:w-6 tw:ml-2" />
</Link>
</p>
</Popout>

View file

@ -135,7 +135,7 @@ export const Pattern = ({ id, Link }) => {
if (!edit)
return (
<div className="tw-w-full">
<div className="tw:w-full">
{pattern.public ? (
<Popout note>
<h5>This is the private view of your pattern</h5>
@ -144,9 +144,9 @@ export const Pattern = ({ id, Link }) => {
<br />
But only you can access this private view.
</p>
<p className="tw-text-right">
<p className="tw:text-right">
<Link
className={`tw-daisy-btn tw-daisy-btn-secondary hover:tw-text-secondary-content hover:tw-no-underline`}
className={`tw:daisy-btn tw:daisy-btn-secondary tw:hover:text-secondary-content tw:hover:no-underline`}
href={`/pattern?id=${pattern.id}`}
>
<PatternIcon />
@ -166,7 +166,7 @@ export const Pattern = ({ id, Link }) => {
)
return (
<div className="tw-w-full">
<div className="tw:w-full">
<h2>Edit pattern {pattern.name}</h2>
{/* Name is always shown */}
@ -204,10 +204,10 @@ export const Pattern = ({ id, Link }) => {
{
val: true,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-flex-wrap tw-justify-between tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:justify-between tw:w-full">
<span>Public Pattern</span>
<OkIcon
className="tw-w-8 tw-h-8 tw-text-success tw-bg-base-100 tw-rounded-full tw-p-1"
className="tw:w-8 tw:h-8 tw:text-success tw:bg-base-100 tw:rounded-full tw:p-1"
stroke={4}
/>
</div>
@ -217,10 +217,10 @@ export const Pattern = ({ id, Link }) => {
{
val: false,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-flex-wrap tw-justify-between tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:justify-between tw:w-full">
<span>Private Pattern</span>
<NoIcon
className="tw-w-8 tw-h-8 tw-text-error tw-bg-base-100 tw-rounded-full tw-p-1"
className="tw:w-8 tw:h-8 tw:text-error tw:bg-base-100 tw:rounded-full tw:p-1"
stroke={3}
/>
</div>
@ -237,15 +237,15 @@ export const Pattern = ({ id, Link }) => {
{account.control >= controlConfig.account.patterns.notes ? (
<MarkdownInput id="pattern-notes" label="Notes" update={setNotes} current={notes} />
) : null}
<div className="tw-flex tw-flex-row tw-items-center tw-align-end tw-gap-2 tw-mt-8">
<div className="tw:flex tw:flex-row tw:items-center tw:align-end tw:gap-2 tw:mt-8">
<button
onClick={() => setEdit(false)}
className={`tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline`}
className={`tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline`}
>
<ResetIcon />
Cancel
</button>
<button onClick={save} className="tw-daisy-btn tw-daisy-btn-primary tw-grow">
<button onClick={save} className="tw:daisy-btn tw:daisy-btn-primary tw:grow">
<UploadIcon />
Save Pattern
</button>
@ -272,7 +272,7 @@ export const PatternCard = ({
const s = sizes[size]
const wrapperProps = {
className: `tw-bg-base-300 tw-w-full tw-mb-2 tw-mx-auto tw-flex tw-flex-col tw-items-start tw-text-center tw-justify-center tw-rounded tw-shadow tw-py-4 tw-w-${s} tw-aspect-square`,
className: `tw:bg-base-300 tw:w-full tw:mb-2 tw:mx-auto tw:flex tw:flex-col tw:items-start tw:text-center tw:justify-center tw:rounded tw:shadow tw:py-4 tw:w-${s} tw:aspect-square`,
style: {
backgroundImage: `url(${cloudflareImageUrl({ type: 'w1000', id: pattern.img })})`,
backgroundSize: 'cover',
@ -315,7 +315,7 @@ export const PatternCard = ({
const BadgeLink = ({ label, href }) => (
<a
href={href}
className="tw-daisy-badge tw-daisy-badge-secondary tw-font-bold tw-daisy-badge-lg hover:tw-text-secondary-content hover:tw-no-underline"
className="tw:daisy-badge tw:daisy-badge-secondary tw:font-bold tw:daisy-badge-lg tw:hover:text-secondary-content tw:hover:no-underline"
>
{label}
</a>
@ -336,19 +336,19 @@ const PatternHeader = ({
}) => (
<>
<h2>{pattern.name}</h2>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-2 tw-text-sm tw-items-center tw-mb-2">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-2 tw:text-sm tw:items-center tw:mb-2">
<KeyVal k="ID" val={pattern.id} color="secondary" />
<KeyVal k="Created" val={<TimeAgo iso={pattern.createdAt} />} color="secondary" />
<KeyVal k="Updated" val={<TimeAgo iso={pattern.updatedAt} />} color="secondary" />
<KeyVal k="Public" val={pattern.public ? 'yes' : 'no'} color="secondary" />
</div>
<div className="tw-flex tw-flex-wrap md:tw-flex-nowrap tw-flex-row tw-gap-2 tw-w-full">
<div className="tw-w-full md:tw-w-96 tw-shrink-0">
<div className="tw:flex tw:flex-wrap tw:md:flex-nowrap tw:flex-row tw:gap-2 tw:w-full">
<div className="tw:w-full tw:md:w-96 tw:shrink-0">
<PatternCard pattern={pattern} size="md" Link={Link} />
</div>
<div className="tw-flex tw-flex-col tw-justify-end tw-gap-2 tw-mb-2 tw-grow">
<div className="tw:flex tw:flex-col tw:justify-end tw:gap-2 tw:mb-2 tw:grow">
{account.control > 3 && (pattern?.public || pattern.userId === account.id) ? (
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center">
<BadgeLink label="JSON" href={`${urls.backend}/patterns/${pattern.id}.json`} />
<BadgeLink label="YAML" href={`${urls.backend}/patterns/${pattern.id}.yaml`} />
</div>
@ -358,12 +358,12 @@ const PatternHeader = ({
<button
onClick={() =>
setModal(
<ModalWrapper flex="col" justify="top lg:tw-justify-center" slideFrom="right">
<ModalWrapper flex="col" justify="top tw:lg:justify-center" slideFrom="right">
<img src={cloudflareImageUrl({ type: 'public', id: pattern.img })} />
</ModalWrapper>
)
}
className={`tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline ${horFlexClasses}`}
>
<ShowcaseIcon />
Show Image
@ -371,7 +371,7 @@ const PatternHeader = ({
{account.control > 3 ? (
<button
onClick={() => togglePublic()}
className={`tw-daisy-btn tw-daisy-btn-${pattern.public ? 'error' : 'success'} tw-daisy-btn-outline ${horFlexClasses} hover:tw-text-${pattern.public ? 'error' : 'success'}-content`}
className={`tw:daisy-btn tw:daisy-btn-${pattern.public ? 'error' : 'success'} tw:daisy-btn-outline ${horFlexClasses} hover:tw:text-${pattern.public ? 'error' : 'success'}-content`}
>
{pattern.public ? <BoolNoIcon /> : <BoolYesIcon />}
Make pattern {pattern.public ? 'private' : 'public'}
@ -381,19 +381,19 @@ const PatternHeader = ({
<>
<Link
href={patternUrlFromState(pattern, true)}
className={`tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline ${horFlexClasses}`}
>
<FreeSewingIcon /> Update Pattern
</Link>
<button
className={`tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline ${horFlexClasses}`}
onClick={clone}
>
<CloneIcon /> Clone Pattern
</button>
<button
onClick={() => setEdit(true)}
className={`tw-daisy-btn tw-daisy-btn-primary ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-primary ${horFlexClasses}`}
>
<EditIcon /> Edit Pattern Metadata
</button>

View file

@ -89,16 +89,16 @@ export const Patterns = ({ Link = false }) => {
return (
<>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-2 tw-items-center tw-justify-between tw-mb-4">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-2 tw:items-center tw:justify-between tw:mb-4">
<button
className="tw-daisy-btn tw-daisy-btn-error"
className="tw:daisy-btn tw:daisy-btn-error"
onClick={removeSelectedPatterns}
disabled={count < 1}
>
<TrashIcon /> {count} {t('patterns')}
</button>
<Link
className="tw-daisy-btn tw-daisy-btn-primary tw-capitalize tw-w-full md:tw-w-auto hover:tw-text-primary-content"
className="tw:daisy-btn tw:daisy-btn-primary tw:capitalize tw:w-full tw:md:w-auto tw:hover:text-primary-content"
href="/editor/"
>
<PlusIcon />
@ -106,13 +106,13 @@ export const Patterns = ({ Link = false }) => {
</Link>
</div>
<TableWrapper>
<table className="tw-table tw-table-auto">
<thead className="tw-border tw-border-base-300 tw-border-b-2 tw-border-t-0 tw-border-x-0">
<table className="tw:table tw:table-auto">
<thead className="tw:border tw:border-base-300 tw:border-b-2 tw:border-t-0 tw:border-x-0">
<tr className="">
<th className="">
<input
type="checkbox"
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={toggleAll}
checked={patterns.length === count}
/>
@ -120,13 +120,13 @@ export const Patterns = ({ Link = false }) => {
{Object.keys(fields).map((field) => (
<th key={field}>
<button
className="tw-daisy-btn tw-daisy-btn-link tw-capitalize tw-px-0 tw-underline hover:tw-decoration-4 tw-decoration-2 tw-text-secondary"
className="tw:daisy-btn tw:daisy-btn-link tw:capitalize tw:px-0 tw:underline tw:hover:decoration-4 tw:decoration-2 tw:text-secondary"
onClick={() => (order === field ? setDesc(!desc) : setOrder(field))}
>
{fields[field]}{' '}
<RightIcon
stroke={3}
className={`tw-w-4 tw-h-4 ${desc ? 'tw--' : 'tw-'}rotate-90 ${order === field ? '' : 'tw-opacity-0'}`}
className={`tw:w-4 tw:h-4 ${desc ? 'tw:-' : 'tw:'}rotate-90 ${order === field ? '' : 'tw:opacity-0'}`}
/>
</button>
</th>
@ -136,16 +136,16 @@ export const Patterns = ({ Link = false }) => {
<tbody>
{orderBy(patterns, order, desc ? 'desc' : 'asc').map((pattern, i) => (
<tr key={i}>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">
<input
type="checkbox"
checked={selection[pattern.id] ? true : false}
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={() => toggle(pattern.id)}
/>
</td>
<td className="tw-text-base tw-font-medium">{pattern.id}</td>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">{pattern.id}</td>
<td className="tw:text-base tw:font-medium">
<PatternCard
href={`/account/data/patterns/pattern?id=${pattern.id}`}
pattern={pattern}
@ -153,24 +153,24 @@ export const Patterns = ({ Link = false }) => {
Link={Link}
/>
</td>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">
<Link
href={`/account/data/patterns/pattern?id=${pattern.id}`}
className="tw-text-secondary tw-underline tw-decoration-2 hover:tw-decoration-4"
className="tw:text-secondary tw:underline tw:decoration-2 tw:hover:decoration-4"
>
{pattern.name}
</Link>
</td>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">
<Link
href={`/designs/${pattern.design}`}
className="tw-text-secondary tw-underline tw-decoration-2 hover:tw-decoration-4"
className="tw:text-secondary tw:underline tw:decoration-2 tw:hover:decoration-4"
>
{capitalize(pattern.design)}
</Link>
</td>
<td className="tw-text-base tw-font-medium">{shortDate(pattern.createdAt)}</td>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">{shortDate(pattern.createdAt)}</td>
<td className="tw:text-base tw:font-medium">
{pattern.public ? <BoolYesIcon /> : <BoolNoIcon />}
</td>
</tr>

View file

@ -56,7 +56,7 @@ const Platform = ({ platform = false }) => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<StringInput
id={`account-${platform}`}
label={platform === 'website' ? `Website URL` : `${labels[platform]} account`}
@ -65,9 +65,9 @@ const Platform = ({ platform = false }) => {
valid={(val) => val.length > 0}
placeholder={'joostdecock'}
/>
<p className="tw-text-right">
<p className="tw:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto tw:mt-8"
onClick={save}
>
<SaveIcon /> Save

View file

@ -32,7 +32,7 @@ export const Reload = () => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<p>
The data stored in your browser can sometimes get out of sync with the data stored in our
backend.

View file

@ -48,22 +48,22 @@ export const Remove = () => {
)
return (
<div className="tw-w-full">
<div className="tw:w-full">
<IconButton
onClick={() =>
setModal(
<ModalWrapper keepOpenOnClick>
<div className="tw-text-center tw-w-full">
<div className="tw:text-center tw:w-full">
<h2>There is no way back from this</h2>
<p>If this is what you want, then go ahead.</p>
<IconButton onClick={removeAccount} color="error" className="tw-mx-auto">
<IconButton onClick={removeAccount} color="error" className="tw:mx-auto">
<TrashIcon />
Remove your FreeSewing account
</IconButton>
<IconButton
onClick={clearModal}
color="primary"
className="tw-mx-auto tw-daisy-btn-outline tw-mt-4"
className="tw:mx-auto tw:daisy-btn-outline tw:mt-4"
>
<ExitIcon />
Back to safety

View file

@ -53,7 +53,7 @@ export const Restrict = ({ Link = false }) => {
)
return (
<div className="tw-w-full">
<div className="tw:w-full">
<p>
The GDPR guarantees{' '}
<Link href="/docs/about/rights/#the-right-to-restrict-processing" className={linkClasses}>
@ -66,21 +66,21 @@ export const Restrict = ({ Link = false }) => {
onClick={() =>
setModal(
<ModalWrapper keepOpenOnClick>
<div className="tw-text-center tw-w-full tw-max-w-xl">
<div className="tw:text-center tw:w-full tw:max-w-xl">
<h2>Proceed with caution</h2>
<p>
While no data will be removed, this will disable your account. Furthermore, you
can not undo this on your own, but will have to contact support when you want to
restore access to your account.
</p>
<IconButton onClick={restrictAccount} color="error" className="tw-mx-auto">
<IconButton onClick={restrictAccount} color="error" className="tw:mx-auto">
<NoIcon stroke={3} />
Restrict processing of your FreeSewing data
</IconButton>
<IconButton
onClick={clearModal}
color="primary"
className="tw-mx-auto tw-daisy-btn-outline tw-mt-4"
className="tw:mx-auto tw:daisy-btn-outline tw:mt-4"
>
<BackIcon />
Back to safety

View file

@ -208,21 +208,21 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
const heading = (
<>
<div className="tw-flex tw-flex-wrap md:tw-flex-nowrap tw-flex-row tw-gap-2 tw-w-full">
<div className="tw-w-full md:tw-w-96 tw-shrink-0">
<div className="tw:flex tw:flex-wrap tw:md:flex-nowrap tw:flex-row tw:gap-2 tw:w-full">
<div className="tw:w-full tw:md:w-96 tw:shrink-0">
<MsetCard set={mset} control={control} Link={Link} />
</div>
<div className="tw-flex tw-flex-col tw-justify-end tw-gap-2 tw-mb-2 tw-grow">
<div className="tw:flex tw:flex-col tw:justify-end tw:gap-2 tw:mb-2 tw:grow">
{account.control > 2 && mset.public && mset.userId !== account.id ? (
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center">
<a
className="tw-daisy-badge tw-daisy-badge-secondary tw-font-bold tw-daisy-badge-lg"
className="tw:daisy-badge tw:daisy-badge-secondary tw:font-bold tw:daisy-badge-lg"
href={`${urls.backend}/sets/${mset.id}.json`}
>
JSON
</a>
<a
className="tw-daisy-badge tw-daisy-badge-success tw-font-bold tw-daisy-badge-lg"
className="tw:daisy-badge tw:daisy-badge-success tw:font-bold tw:daisy-badge-lg"
href={`${urls.backend}/sets/${mset.id}.yaml`}
>
YAML
@ -232,9 +232,9 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
<span></span>
)}
{account.control > 3 && mset.userId === account.id ? (
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center">
<button
className="tw-daisy-badge tw-daisy-badge-secondary tw-font-bold tw-daisy-badge-lg"
className="tw:daisy-badge tw:daisy-badge-secondary tw:font-bold tw:daisy-badge-lg"
onClick={() =>
setModal(
<ModalWrapper keepOpenOnClick>
@ -246,7 +246,7 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
JSON
</button>
<button
className="tw-daisy-badge tw-daisy-badge-success tw-font-bold tw-daisy-badge-lg tw-text-neutral-content"
className="tw:daisy-badge tw:daisy-badge-success tw:font-bold tw:daisy-badge-lg tw:text-neutral-content"
onClick={() =>
setModal(
<ModalWrapper keepOpenOnClick>
@ -263,11 +263,11 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
)}
{account.id && account.control > 2 && mset.public && mset.userId !== account.id ? (
<button
className="tw-daisy-btn tw-daisy-btn-primary"
className="tw:daisy-btn tw:daisy-btn-primary"
title="Import measurements set"
onClick={importSet}
>
<div className="tw-flex tw-flex-row tw-gap-4 tw-justify-between tw-items-center tw-w-full">
<div className="tw:flex tw:flex-row tw:gap-4 tw:justify-between tw:items-center tw:w-full">
<UploadIcon />
Import measurements set
</div>
@ -284,7 +284,7 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
</ModalWrapper>
)
}
className={`tw-daisy-btn tw-daisy-btn-secondary tw-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-secondary tw:btn-outline ${horFlexClasses}`}
>
<ShowcaseIcon />
Show Image
@ -297,9 +297,9 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
setSuggest(!suggest)
setEdit(false)
}}
className={`tw-daisy-btn ${
suggest ? 'tw-daisy-btn-neutral' : 'tw-daisy-btn-primary'
} tw-daisy-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn ${
suggest ? 'tw:daisy-btn-neutral' : 'tw:daisy-btn-primary'
} tw:daisy-btn-outline ${horFlexClasses}`}
>
{suggest ? <ResetIcon /> : <CuratedMeasurementsSetIcon />}
{suggest ? 'Cancel' : 'Suggest for curation'}
@ -312,14 +312,14 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
setEdit(false)
setSuggest(false)
}}
className={`tw-daisy-btn tw-daisy-btn-neutral tw-daisy-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-neutral tw:daisy-btn-outline ${horFlexClasses}`}
>
<ResetIcon />
Cancel
</button>
<button
onClick={save}
className={`tw-daisy-btn tw-daisy-btn-primary ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-primary ${horFlexClasses}`}
>
<UploadIcon />
Save measurements set
@ -331,7 +331,7 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
setEdit(true)
setSuggest(false)
}}
className={`tw-daisy-btn tw-daisy-btn-primary ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-primary ${horFlexClasses}`}
>
<EditIcon /> Edit measurements set
</button>
@ -340,14 +340,14 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
)}
{account.control > 1 && account?.compare ? (
<button
className="tw-daisy-btn tw-daisy-btn-secondary tw-btn-outline"
className="tw:daisy-btn tw:daisy-btn-secondary tw:btn-outline"
title="Validate measurements"
onClick={() => {
setRender(!render)
setEdit(false)
}}
>
<div className="tw-flex tw-flex-row tw-gap-4 tw-justify-between tw-items-center tw-w-full">
<div className="tw:flex tw:flex-row tw:gap-4 tw:justify-between tw:items-center tw:w-full">
<CompareIcon />
Validate measurements
</div>
@ -355,11 +355,11 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
) : null}
{account.control > 2 && mset.userId === account.id ? (
<button
className="tw-daisy-btn tw-daisy-btn-neutral"
className="tw:daisy-btn tw:daisy-btn-neutral"
title="Clone measurements set"
onClick={importSet}
>
<div className="tw-flex tw-flex-row tw-gap-4 tw-justify-between tw-items-center tw-w-full">
<div className="tw:flex tw:flex-row tw:gap-4 tw:justify-between tw:items-center tw:w-full">
<CloneIcon />
Clone measurements set
</div>
@ -367,13 +367,13 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
) : null}
</div>
</div>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-4 tw-text-sm tw-items-center tw-justify-between tw-mb-2"></div>
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-4 tw:text-sm tw:items-center tw:justify-between tw:mb-2"></div>
</>
)
if (suggest)
return (
<div className="tw-w-full">
<div className="tw:w-full">
{heading}
<SuggestCset {...{ mset, setLoadingStatus, backend, Link }} />
</div>
@ -382,14 +382,14 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
if (!edit) {
if (render)
return (
<div className="tw-w-full">
<div className="tw:w-full">
{heading}
<RenderedCSet {...{ mset, setLoadingStatus, backend, imperial }} />
</div>
)
return (
<div className="tw-w-full">
<div className="tw:w-full">
{heading}
<h2>Data</h2>
@ -404,14 +404,14 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
<>
{mset.userId === account.id && (
<DisplayRow title="Public">
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-justify-between">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:justify-between">
{mset.public ? (
<OkIcon className="tw-w-6 tw-h-6 tw-text-success" stroke={4} />
<OkIcon className="tw:w-6 tw:h-6 tw:text-success" stroke={4} />
) : (
<NoIcon className="tw-w-6 tw-h-6 tw-text-error" stroke={3} />
<NoIcon className="tw:w-6 tw:h-6 tw:text-error" stroke={3} />
)}
<button
className="tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-sm"
className="tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-sm"
onClick={togglePublic}
>
Make {mset.public ? 'Private' : 'Public'}
@ -432,13 +432,13 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
{control >= controlConfig.account.sets.createdAt && (
<DisplayRow title="Created">
{timeAgo(mset.createdAt, false)}
<span className="tw-text-sm tw-pl-2">({shortDate(mset.createdAt, false)})</span>
<span className="tw:text-sm tw:pl-2">({shortDate(mset.createdAt, false)})</span>
</DisplayRow>
)}
{control >= controlConfig.account.sets.updatedAt && (
<DisplayRow title="Updated">
{timeAgo(mset.updatedAt, false)}
<span className="tw-text-sm tw-pl-2">({shortDate(mset.updatedAt, false)})</span>
<span className="tw:text-sm tw:pl-2">({shortDate(mset.updatedAt, false)})</span>
</DisplayRow>
)}
{control >= controlConfig.account.sets.id && <DisplayRow title="ID">{mset.id}</DisplayRow>}
@ -458,7 +458,7 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
title={<MeasurementValue {...{ m, val, imperial: !displayAsMetric }} />}
key={m}
>
<span className="tw-font-medium">{measurementTranslations[m]}</span>
<span className="tw:font-medium">{measurementTranslations[m]}</span>
</DisplayRow>
) : null
)}
@ -469,10 +469,10 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
{heading}
<h2 id="measies">Measurements</h2>
<div className="tw-bg-secondary tw-px-4 tw-pt-1 tw-pb-4 tw-rounded-lg tw-shadow tw-bg-opacity-10">
<div className="tw:bg-secondary/10 tw:px-4 tw:pt-1 tw:pb-4 tw:rounded-lg tw:shadow">
<DesignInput
update={setFilter}
label="Filter by design"
@ -531,10 +531,10 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
{
val: true,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-flex-wrap tw-justify-between tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:justify-between tw:w-full">
<span>Public measurements set</span>
<OkIcon
className="tw-w-8 tw-h-8 tw-text-success tw-bg-base-100 tw-rounded-full tw-p-1"
className="tw:w-8 tw:h-8 tw:text-success tw:bg-base-100 tw:rounded-full tw:p-1"
stroke={4}
/>
</div>
@ -544,10 +544,10 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
{
val: false,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-flex-wrap tw-justify-between tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:justify-between tw:w-full">
<span>Private measurements set</span>
<NoIcon
className="tw-w-8 tw-h-8 tw-text-error tw-bg-base-100 tw-rounded-full tw-p-1"
className="tw:w-8 tw:h-8 tw:text-error tw:bg-base-100 tw:rounded-full tw:p-1"
stroke={3}
/>
</div>
@ -571,9 +571,9 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
{
val: false,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-flex-wrap tw-justify-between tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:justify-between tw:w-full">
<span>Metric units (cm)</span>
<span className="tw-text-inherit tw-text-2xl tw-pr-2">cm</span>
<span className="tw:text-inherit tw:text-2xl tw:pr-2">cm</span>
</div>
),
desc: 'Pick this if you prefer cm over inches',
@ -581,9 +581,9 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
{
val: true,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-flex-wrap tw-justify-between tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:justify-between tw:w-full">
<span>Imperial units (inch)</span>
<span className="tw-text-inherit tw-text-4xl tw-pr-2"></span>
<span className="tw:text-inherit tw:text-4xl tw:pr-2"></span>
</div>
),
desc: 'Pick this if you prefer inches over cm',
@ -591,7 +591,7 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
]}
current={imperial}
/>
<span className="tw-text-large tw-text-warning">
<span className="tw:text-large tw:text-warning">
Note: You must save after changing Units to have the change take effect on this page.
</span>
</>
@ -610,7 +610,7 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
) : null}
<button
onClick={save}
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-lg tw-flex tw-flex-row tw-items-center tw-gap-4 tw-mx-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-lg tw:flex tw:flex-row tw:items-center tw:gap-4 tw:mx-auto tw:mt-8"
>
<UploadIcon />
Save Measurements Set
@ -685,7 +685,7 @@ export const SuggestCset = ({ mset, Link }) => {
return (
<>
<h2>Suggest a measurements set for curation</h2>
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2">
{missing.length > 0 ? <BoolNoIcon /> : <BoolYesIcon />}
Measurements
</h4>
@ -696,7 +696,7 @@ export const SuggestCset = ({ mset, Link }) => {
of measurements.
</p>
<p>Your measurements set is missing the following measurements:</p>
<ul className="tw-list tw-list-inside tw-list-disc tw-ml-4">
<ul className="tw:list tw:list-inside tw:list-disc tw:ml-4">
{missing.map((m) => (
<li key={m}>{m}</li>
))}
@ -705,13 +705,13 @@ export const SuggestCset = ({ mset, Link }) => {
) : (
<p>All measurements are available.</p>
)}
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2">
{name.length > 1 ? <BoolYesIcon /> : <BoolNoIcon />}
Name
</h4>
<p>Each curated set has a name. You can suggest your own name or a pseudonym.</p>
<StringInput label="Name" current={name} update={setName} valid={(val) => val.length > 1} />
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2">
{height.length > 1 ? <BoolYesIcon /> : <BoolNoIcon />}
Height
</h4>
@ -725,7 +725,7 @@ export const SuggestCset = ({ mset, Link }) => {
update={setHeight}
valid={(val) => val.length > 1}
/>
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2 tw-mt-4">
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2 tw:mt-4">
{img.length > 0 ? <BoolYesIcon /> : <BoolNoIcon />}
Image
</h4>
@ -740,7 +740,7 @@ export const SuggestCset = ({ mset, Link }) => {
update={setImg}
valid={(val) => val.length > 1}
/>
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2 tw-mt-4">
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2 tw:mt-4">
<BoolYesIcon />
Notes
</h4>
@ -750,7 +750,7 @@ export const SuggestCset = ({ mset, Link }) => {
</Popout>
<MarkdownInput label="Notes" current={notes} update={setNotes} valid={() => true} />
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full tw-mt-4"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:mt-4"
disabled={!(missing.length === 0 && height.length > 1 && img.length > 0)}
onClick={suggestSet}
>
@ -776,10 +776,10 @@ export const RenderedCSet = ({ mset, imperial }) => {
if (missing.length > 0)
return (
<>
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2">Validation messages</h4>
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2">Validation messages</h4>
<p>To validate and preview a measurement set, all measurements need to be entered.</p>
<p>Your measurements set is missing the following measurements:</p>
<ul className="tw-list tw-list-inside tw-list-disc tw-ml-4">
<ul className="tw:list tw:list-inside tw:list-disc tw:ml-4">
{missing.map((m) => (
<li key={m}>{m}</li>
))}
@ -793,7 +793,7 @@ export const RenderedCSet = ({ mset, imperial }) => {
console.log('flags', pattern, flags, strings)
return (
<>
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2">Measurement analysis</h4>
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2">Measurement analysis</h4>
<p>
Based on your measurements, we estimate your body to be about{' '}
<strong>{formatMm(pattern.parts[0].front.points.head.y * -1, imperial)}</strong> high.
@ -803,7 +803,7 @@ export const RenderedCSet = ({ mset, imperial }) => {
const desc = strings[flag.desc] || flag.desc
return (
<div key={key} className="tw-flex tw-flex-row tw-mt-4">
<div key={key} className="tw:flex tw:flex-row tw:mt-4">
{flag.type === 'warn' ? (
<MiniNote>
<Markdown>{desc}</Markdown>
@ -817,7 +817,7 @@ export const RenderedCSet = ({ mset, imperial }) => {
)
})}
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2 tw-mt-12">Preview</h4>
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2 tw:mt-12">Preview</h4>
{previewVisible ? (
<Pattern
renderProps={pattern.getRenderProps()}
@ -856,7 +856,7 @@ export const RenderedCSet = ({ mset, imperial }) => {
</li>
</ul>
<button
className={`tw-daisy-btn tw-daisy-btn-primary tw-mt-4`}
className={`tw:daisy-btn tw:daisy-btn-primary tw:mt-4`}
onClick={() => setPreviewVisible(true)}
>
<CompareIcon />I understand, render body preview
@ -896,7 +896,7 @@ export const NewSet = () => {
}
return (
<div className="tw-max-w-xl">
<div className="tw:max-w-xl">
<h5>Name</h5>
<p>Give this set of measurements a name. That will help tell them apart.</p>
<StringInput
@ -907,9 +907,9 @@ export const NewSet = () => {
valid={(val) => val && val.length > 0}
placeholder={'Georg Cantor'}
/>
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-w-full tw-mt-8 tw-mb-2">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:w-full tw:mt-8 tw:mb-2">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-grow tw-capitalize"
className="tw:daisy-btn tw:daisy-btn-primary tw:grow tw:capitalize"
disabled={name.length < 1}
onClick={createSet}
>

View file

@ -85,19 +85,19 @@ export const Sets = ({ Link = false }) => {
}
return (
<div className="tw-max-w-7xl xl:tw-pl-4">
<p className="tw-text-center md:tw-text-right">
<div className="tw:max-w-7xl tw:xl:pl-4">
<p className="tw:text-center tw:md:text-right">
<Link
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline tw-capitalize tw-w-full md:tw-w-auto tw-mr-2 tw-mb-2 hover:tw-no-underline hover:tw-text-primary-content"
className="tw:daisy-btn tw:daisy-btn-secondary tw:capitalize tw:w-full tw:md:w-auto tw:mr-2 tw:hover:no-underline tw:hover:text-primary-content no-hover-decoration"
bottom
primary
href="/account/import"
>
<UploadIcon />
Import Measurements Sets
<UploadIcon className="tw:w-6 tw:h-6 tw:text-secondary-content" />
<span className="tw:text-secondary-content">Import Measurements Sets</span>
</Link>
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-capitalize tw-w-full md:tw-w-auto hover:tw-no-underline hover:tw-text-primary-content"
className="tw:daisy-btn tw:daisy-btn-primary tw:capitalize tw:w-full tw:md:w-auto tw:hover:no-underline tw:hover:text-primary-content"
onClick={() =>
setModal(
<ModalWrapper keepOpenOnClick>
@ -110,41 +110,41 @@ export const Sets = ({ Link = false }) => {
Create a new Measurements Set
</button>
</p>
<div className="tw-flex tw-flex-row tw-gap-2 tw-border-b-2 tw-mb-4 tw-pb-4 tw-mt-8 tw-h-14 tw-items-center">
<div className="tw:flex tw:flex-row tw:gap-2 tw:border-b-2 tw:mb-4 tw:pb-4 tw:mt-8 tw:h-14 tw:items-center">
<input
type="checkbox"
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={toggleSelectAll}
checked={sets.length === selCount}
/>
<button
className="tw-daisy-btn tw-daisy-btn-error"
className="tw:daisy-btn tw:daisy-btn-error"
onClick={removeSelectedSets}
disabled={selCount < 1}
>
<TrashIcon /> {selCount} Measurements Sets
</button>
</div>
<div className="tw-grid tw-grid-cols-2 lg:tw-grid-cols-4 tw-gap-2">
<div className="tw:grid tw:grid-cols-2 tw:lg:grid-cols-4 tw:gap-2">
{sets.map((set, i) => (
<div
key={i}
className={`tw-flex tw-flex-row tw-items-start tw-gap-1 tw-border-2
className={`tw:flex tw:flex-row tw:items-start tw:gap-1 tw:border-2
${
selected[set.id]
? 'tw-border-solid tw-border-secondary'
: 'tw-border-dotted tw-border-base-300'
} tw-rounded-lg p-2`}
? 'tw:border-solid tw:border-secondary'
: 'tw:border-dotted tw:border-base-300'
} tw:rounded-lg p-2`}
>
<label className="tw-w-8 tw-h-full tw-shrink-0">
<label className="tw:w-8 tw:h-full tw:shrink-0">
<input
type="checkbox"
checked={selected[set.id] ? true : false}
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={() => toggleSelect(set.id)}
/>
</label>
<div className="tw-w-full">
<div className="tw:w-full">
<MsetCard
control={control}
href={`/account/data/sets/set?id=${set.id}`}
@ -189,9 +189,9 @@ export const MsetCard = ({
const s = sizes[size]
const wrapperProps = {
className: `tw-bg-base-300 tw-aspect-square tw-h-${s} tw-w-${s} tw-mb-2 tw-grow tw-w-full
hover:tw-cursor-pointer tw-border-0 tw-opacity-80 hover:tw-opacity-100
tw-mx-auto tw-flex tw-flex-col tw-items-start tw-text-center tw-justify-between tw-rounded-none md:tw-rounded shadow`,
className: `tw:bg-base-300 tw:aspect-square tw:h-${s} tw:w-${s} tw:mb-2 tw:grow tw:w-full
tw:hover:cursor-pointer tw:border-0 tw:opacity-80 tw:hover:opacity-100
tw:mx-auto tw:flex tw:flex-col tw:items-start tw:text-center tw:justify-between tw:rounded-none tw:md:rounded shadow`,
style: {
backgroundImage: `url(${cloudflareImageUrl({ type: 'w500', id: set.img })})`,
backgroundSize: 'cover',
@ -212,11 +212,11 @@ export const MsetCard = ({
set.measies,
true
)
const iconClasses = 'tw-w-8 tw-h-8 tw-p-1 tw-rounded-full tw--mt-2 tw--ml-2 tw-shadow'
const iconClasses = 'tw:w-8 tw:h-8 tw:p-1 tw:rounded-full tw:-mt-2 tw:-ml-2 tw:shadow'
icon = hasMeasies ? (
<OkIcon className={`${iconClasses} tw-bg-success tw-text-success-content`} stroke={4} />
<OkIcon className={`${iconClasses} tw:bg-success tw:text-success-content`} stroke={4} />
) : (
<NoIcon className={`${iconClasses} tw-bg-error tw-text-error-content`} stroke={3} />
<NoIcon className={`${iconClasses} tw:bg-error tw:text-error-content`} stroke={3} />
)
if (missing.length > 0) {
const translated = missing.map((m) => measurementsTranslations[m])
@ -225,7 +225,7 @@ export const MsetCard = ({
const lastSpace = missingString.lastIndexOf(', ', maxLength)
missingString = missingString.substring(0, lastSpace) + ', and more...'
}
const measieClasses = 'tw-font-normal tw-text-xs'
const measieClasses = 'tw:font-normal tw:text-xs'
missingMeasies = <span className={`${measieClasses}`}>{missingString}</span>
linebreak = <br />
}
@ -234,7 +234,7 @@ export const MsetCard = ({
const inner = (
<>
{icon}
<span className="tw-bg-neutral tw-text-neutral-content tw-px-4 tw-w-full tw-bg-opacity-50 tw-py-2 tw-rounded tw-rounded-t-none tw-font-bold tw-leading-5">
<span className="tw:bg-neutral/50 tw:text-neutral-content tw:px-4 tw:w-full tw:py-2 tw:rounded tw:rounded-t-none tw:font-bold tw:leading-5">
{set.name}
{linebreak}
{missingMeasies}

View file

@ -54,14 +54,14 @@ export const Units = ({ welcome = false }) => {
: '/docs/about/guide'
return (
<div className="tw-w-full">
<div className="tw:w-full">
<ListInput
id="account-units"
label="Units"
list={['metric', 'imperial'].map((val) => ({
val,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-w-full tw-justify-between">
<div className="tw:flex tw:flex-row tw:items-center tw:w-full tw:justify-between">
<span>{val === 'metric' ? 'Metric units (cm)' : 'Imperial units (inch)'}</span>
<NumberCircle nr={val === 'imperial' ? '″' : 'cm'} color="secondary" />
</div>
@ -76,17 +76,17 @@ export const Units = ({ welcome = false }) => {
/>
{welcome ? (
<>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[account?.control].length > 0 ? (
<>
<progress
className="tw-daisy-progress tw-daisy-progress-primary tw-w-full tw-mt-12"
className="tw:daisy-progress tw:daisy-progress-primary tw:w-full tw:mt-12"
value={300 / welcomeSteps[account?.control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
3 / {welcomeSteps[account?.control].length}
</span>
<WelcomeIcons

View file

@ -60,7 +60,7 @@ export const Username = ({ welcome = false, Link = false }) => {
else btnClasses += 'w-full daisy-btn-primary'
return (
<div className="tw-w-full">
<div className="tw:w-full">
<StringInput
id="account-username"
label="Username"
@ -69,24 +69,24 @@ export const Username = ({ welcome = false, Link = false }) => {
valid={() => available}
placeholder={'Sorcha Ni Dhubghaill'}
labelBL={
<span className="tw-flex tw-flex-row tw-gap-1 tw-items-center">
<span className="tw:flex tw:flex-row tw:gap-1 tw:items-center">
{available ? (
<>
<OkIcon className="tw-w-4 tw-h-4 tw-text-success" stroke={4} /> Username is
<OkIcon className="tw:w-4 tw:h-4 tw:text-success" stroke={4} /> Username is
available
</>
) : (
<>
<NoIcon className="tw-w-4 tw-h-4 tw-text-error" stroke={3} /> This username is taken
<NoIcon className="tw:w-4 tw:h-4 tw:text-error" stroke={3} /> This username is taken
</>
)}
</span>
}
/>
<p className="tw-text-right">
<p className="tw:text-right">
<button
disabled={!available}
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto tw:mt-8"
onClick={save}
>
<SaveIcon /> Save Username
@ -95,17 +95,17 @@ export const Username = ({ welcome = false, Link = false }) => {
{welcome ? (
<>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[account.control].length > 0 ? (
<>
<progress
className="tw-daisy-progress tw-daisy-progress-primary tw-w-full tw-mt-12"
className="tw:daisy-progress tw:daisy-progress-primary tw:w-full tw:mt-12"
value={500 / welcomeSteps[account.control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
5 / {welcomeSteps[account.control].length}
</span>
<WelcomeIcons

View file

@ -17,14 +17,14 @@ import {
/*
* A component to display a row of data
*/
export const DisplayRow = ({ title, children, keyWidth = 'tw-w-24' }) => (
<div className="tw-flex tw-flex-row tw-flex-wrap tw-items-center lg:tw-gap-4 tw-my-2 tw-w-full">
export const DisplayRow = ({ title, children, keyWidth = 'tw:w-24' }) => (
<div className="tw:flex tw:flex-row tw:flex-wrap tw:items-center tw:lg:gap-4 tw:my-2 tw:w-full">
<div
className={`${keyWidth} tw-text-left md:tw-text-right tw-block md:tw-inline tw-font-bold tw-pr-4 tw-shrink-0`}
className={`${keyWidth} tw:text-left tw:md:text-right tw:block tw:md:inline tw:font-bold tw:pr-4 tw:shrink-0`}
>
{title}
</div>
<div className="tw-grow">{children}</div>
<div className="tw:grow">{children}</div>
</div>
)
@ -37,14 +37,14 @@ export const welcomeSteps = {
}
export const WelcomeDoneIcon = ({ href }) => (
<Link href={`/welcome/${href}`} className="tw-text-success hover:tw-text-secondary">
<Link href={`/welcome/${href}`} className="tw:text-success tw:hover:text-secondary">
<WelcomeTopicIcon href={href} />
</Link>
)
export const WelcomeTodoIcon = ({ href }) => (
<Link
href={`/welcome/${href}`}
className="tw-text-secondary tw-w-6 tw-h-6 tw-opacity-50 hover:tw-opacity-100"
className="tw:text-secondary tw:w-6 tw:h-6 tw:opacity-50 tw:hover:opacity-100"
>
<WelcomeTopicIcon href={href} />
</Link>
@ -62,11 +62,11 @@ const WelcomeTopicIcon = (props) => {
}
const WelcomeDoingIcon = ({ href }) => (
<WelcomeTopicIcon href={href} className="tw-w-6 tw-h-6 tw-text-base-content" />
<WelcomeTopicIcon href={href} className="tw:w-6 tw:h-6 tw:text-base-content" />
)
export const WelcomeIcons = ({ done = [], todo = [], current = '' }) => (
<div className="tw-m-auto tw-flex tw-flex-row tw-items-center tw-justify-center tw-gap-2">
<div className="tw:m-auto tw:flex tw:flex-row tw:items-center tw:justify-center tw:gap-2">
{done.map((href) => (
<WelcomeDoneIcon href={href} key={href} />
))}