1
0
Fork 0
freesewing/packages/react/components/Editor/components/views/SaveView.mjs
2025-06-01 17:02:46 +02:00

172 lines
5.9 KiB
JavaScript

// Dependencies
import yaml from 'js-yaml'
import { capitalize, shortDate, notEmpty } from '@freesewing/utils'
import { linkClasses } from '@freesewing/utils'
// Hooks
import React, { useState } from 'react'
import { useBackend } from '@freesewing/react/hooks/useBackend'
// Components
import { RoleBlock } from '@freesewing/react/components/Role'
import { Popout } from '@freesewing/react/components/Popout'
import { StringInput, MarkdownInput } from '@freesewing/react/components/Input'
import { SaveAsIcon, SaveIcon } from '@freesewing/react/components/Icon'
import { H1 } from '@freesewing/react/components/Heading'
import { Link, SuccessLink } from '@freesewing/react/components/Link'
import { HeaderMenu } from '../HeaderMenu.mjs'
/**
* This is the save view, it allows you to save your pattern to a FreeSewing account
*
* @param {Object} props - All the props
* @param {Function} props.config - The editor configuration
* @param {Object} props.state - The editor state object
* @param {Object} props.update - Helper object for updating the editor state
*/
export const SaveView = ({ config, state, update }) => {
const { settings = {} } = state // Guard against undefined settings
// Hooks
const backend = useBackend()
// State
const [name, setName] = useState(`${capitalize(state.design)} / ${shortDate()}`)
const [withNotes, setWithNotes] = useState(false)
const [notes, setNotes] = useState('')
const [savedId, setSavedId] = useState()
const [saveAs] = useState(false) // FIXME
const addSettingsToNotes = () => {
setNotes(notes + '\n\n#### Settings\n\n```yaml\n' + yaml.dump(settings) + '\n````')
}
const saveAsNewPattern = async () => {
const loadingId = 'savePatternAs'
update.startLoading(loadingId)
const patternData = {
design: state.design,
name,
public: false,
settings,
data: {},
}
if (withNotes) patternData.notes = notes
const result = await backend.createPattern(patternData)
if (result[0] === 201 && result[1].pattern.id) {
const id = result[1].pattern.id
update.stopLoading(loadingId)
update.view('draft')
update.pid(id)
update.notifySuccess(
<span>
{' '}
Pattern saved as:{' '}
<SuccessLink href={`/account/data/patterns/pattern?id=${id}`}> #{id} </SuccessLink>
</span>,
id
)
} else update.notifyFailure('oops', loadingId)
}
const savePattern = async () => {
const loadingId = 'savePattern'
update.startLoading(loadingId)
const patternData = {
design: state.design,
settings,
name,
public: false,
data: {},
}
const result = await backend.updatePattern(saveAs.pattern, patternData)
if (result.success) {
update.stopLoading(loadingId)
setSavedId(saveAs.pattern)
update.notifySuccess('Pattern saved', loadingId)
}
}
return (
<RoleBlock user>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw:m-auto tw:mt-8 tw:max-w-2xl tw:px-4">
{saveAs && saveAs.pattern ? (
<>
<h2>Save Pattern</h2>
{savedId && (
<Popout type="link">
<h5>Pattern Saved</h5>
See: <Link href={`/account/patterns/${savedId}`}>/account/patterns/{savedId}</Link>
</Popout>
)}
<button
className={`tw:flex tw:flex-row tw:items-center tw:gap-2 tw:btn tw:btn-primary tw:btn-lg tw:w-full tw:mt-2 tw:my-8`}
onClick={savePattern}
>
<SaveIcon className="tw:h-8 tw:w-8" />
Save Pattern #{saveAs.pattern}
</button>
</>
) : null}
<H1>Save As New Pattern</H1>
<div className="tw:mb-4">
<StringInput
label="Pattern title"
current={name}
update={setName}
valid={notEmpty}
labelBR={
<>
{withNotes ? (
<div className="tw:flex tw:flex-row tw:items-center tw:gap-4">
<button
className={`tw:font-bold ${linkClasses}`}
onClick={() => setWithNotes(false)}
>
Hide notes
</button>
<button className={`tw:font-bold ${linkClasses}`} onClick={addSettingsToNotes}>
Add settings to notes
</button>
</div>
) : (
<button
className={`tw:font-bold ${linkClasses}`}
onClick={() => setWithNotes(true)}
>
Add notes
</button>
)}
</>
}
/>
{withNotes ? (
<MarkdownInput label="Pattern notes" current={notes} update={setNotes} />
) : null}
<div className="tw:flex tw:flex-row tw:gap-2 tw:mt-8">
<button
className={`tw:daisy-btn tw:daisy-btn-primary lg:tw:daisy-btn-lg tw:daisy-btn-outline`}
onClick={update.viewBack}
title="Cancel"
>
<span>Cancel</span>
</button>
<button
className={`tw:flex tw:flex-row tw:items-center tw:justify-between tw:daisy-btn tw:daisy-btn-primary lg:tw:daisy-btn-lg tw:grow`}
onClick={saveAsNewPattern}
title="Save as new pattern"
>
<SaveAsIcon className="tw:w-8 tw:h-8" />
<span>Save as new pattern</span>
</button>
</div>
<p className="tw:text-sm tw:text-right">
To access your saved patterns, go to:
<b>
{' '}
<Link href="/account/data/patterns/">/account/data/patterns</Link>
</b>
</p>
</div>
</div>
</RoleBlock>
)
}