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:
parent
a2863e5158
commit
44e04a4cef
164 changed files with 2361 additions and 2658 deletions
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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="" />
|
||||
|
|
|
@ -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" />
|
||||
</>
|
||||
)
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 />
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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} />
|
||||
))}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue