2023-07-25 10:40:26 -04:00
|
|
|
import {
|
|
|
|
faArrowRotateBack,
|
|
|
|
faCheck,
|
|
|
|
faFolder,
|
|
|
|
faXmark,
|
|
|
|
} from '@fortawesome/free-solid-svg-icons'
|
2023-07-13 07:22:08 -04:00
|
|
|
import { ActionButton } from '../components/ActionButton'
|
|
|
|
import { AppHeader } from '../components/AppHeader'
|
|
|
|
import { open } from '@tauri-apps/api/dialog'
|
2023-07-21 12:48:23 -04:00
|
|
|
import { baseUnits, useStore } from '../useStore'
|
2023-07-13 07:22:08 -04:00
|
|
|
import { useState } from 'react'
|
|
|
|
import { toast } from 'react-hot-toast'
|
2023-07-21 12:48:23 -04:00
|
|
|
import { Toggle } from '../components/Toggle/Toggle'
|
2023-07-25 10:40:26 -04:00
|
|
|
import { useNavigate } from 'react-router-dom'
|
2023-07-13 07:22:08 -04:00
|
|
|
|
|
|
|
export const Settings = () => {
|
2023-07-25 10:40:26 -04:00
|
|
|
const navigate = useNavigate()
|
2023-07-13 07:22:08 -04:00
|
|
|
const {
|
2023-07-21 12:48:23 -04:00
|
|
|
defaultDir: ogDefaultDir,
|
2023-07-13 07:22:08 -04:00
|
|
|
setDefaultDir: saveDefaultDir,
|
2023-07-21 12:48:23 -04:00
|
|
|
defaultProjectName: ogDefaultProjectName,
|
2023-07-13 07:22:08 -04:00
|
|
|
setDefaultProjectName: saveDefaultProjectName,
|
2023-07-21 12:48:23 -04:00
|
|
|
defaultUnitSystem: ogDefaultUnitSystem,
|
|
|
|
setDefaultUnitSystem: saveDefaultUnitSystem,
|
|
|
|
defaultBaseUnit: ogDefaultBaseUnit,
|
|
|
|
setDefaultBaseUnit: saveDefaultBaseUnit,
|
2023-07-21 16:53:06 +10:00
|
|
|
saveDebugPanel,
|
|
|
|
originalDebugPanel,
|
2023-07-25 10:40:26 -04:00
|
|
|
onboardingStatus: ogOnboardingStatus,
|
|
|
|
setOnboardingStatus: saveOnboardingStatus,
|
2023-07-13 07:22:08 -04:00
|
|
|
} = useStore((s) => ({
|
|
|
|
defaultDir: s.defaultDir,
|
|
|
|
setDefaultDir: s.setDefaultDir,
|
|
|
|
defaultProjectName: s.defaultProjectName,
|
|
|
|
setDefaultProjectName: s.setDefaultProjectName,
|
2023-07-21 12:48:23 -04:00
|
|
|
defaultUnitSystem: s.defaultUnitSystem,
|
|
|
|
setDefaultUnitSystem: s.setDefaultUnitSystem,
|
|
|
|
defaultBaseUnit: s.defaultBaseUnit,
|
|
|
|
setDefaultBaseUnit: s.setDefaultBaseUnit,
|
2023-07-21 16:53:06 +10:00
|
|
|
saveDebugPanel: s.setDebugPanel,
|
|
|
|
originalDebugPanel: s.debugPanel,
|
2023-07-25 10:40:26 -04:00
|
|
|
onboardingStatus: s.onboardingStatus,
|
|
|
|
setOnboardingStatus: s.setOnboardingStatus,
|
2023-07-13 07:22:08 -04:00
|
|
|
}))
|
2023-07-21 12:48:23 -04:00
|
|
|
const [defaultDir, setDefaultDir] = useState(ogDefaultDir)
|
|
|
|
const [defaultProjectName, setDefaultProjectName] =
|
|
|
|
useState(ogDefaultProjectName)
|
|
|
|
const [defaultUnitSystem, setDefaultUnitSystem] =
|
|
|
|
useState(ogDefaultUnitSystem)
|
|
|
|
const [defaultBaseUnit, setDefaultBaseUnit] = useState(ogDefaultBaseUnit)
|
2023-07-21 16:53:06 +10:00
|
|
|
const [debugPanel, setDebugPanel] = useState(originalDebugPanel)
|
2023-07-25 10:40:26 -04:00
|
|
|
const [onboardingStatus, setOnboardingStatus] = useState(ogOnboardingStatus)
|
2023-07-13 07:22:08 -04:00
|
|
|
|
|
|
|
async function handleDirectorySelection() {
|
|
|
|
const newDirectory = await open({
|
|
|
|
directory: true,
|
|
|
|
defaultPath: (defaultDir.base || '') + (defaultDir.dir || '/'),
|
|
|
|
title: 'Choose a new default directory',
|
|
|
|
})
|
|
|
|
|
|
|
|
if (newDirectory && newDirectory !== null && !Array.isArray(newDirectory)) {
|
|
|
|
setDefaultDir({ base: defaultDir.base, dir: newDirectory })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const handleSaveClick = () => {
|
|
|
|
saveDefaultDir(defaultDir)
|
|
|
|
saveDefaultProjectName(defaultProjectName)
|
2023-07-21 12:48:23 -04:00
|
|
|
saveDefaultUnitSystem(defaultUnitSystem)
|
|
|
|
saveDefaultBaseUnit(defaultBaseUnit)
|
2023-07-21 16:53:06 +10:00
|
|
|
saveDebugPanel(debugPanel)
|
2023-07-25 10:40:26 -04:00
|
|
|
saveOnboardingStatus(onboardingStatus)
|
2023-07-13 07:22:08 -04:00
|
|
|
toast.success('Settings saved!')
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<AppHeader showToolbar={false}>
|
|
|
|
<ActionButton
|
2023-07-27 18:59:40 -04:00
|
|
|
Element="link"
|
2023-07-13 07:22:08 -04:00
|
|
|
to="/"
|
|
|
|
icon={{
|
|
|
|
icon: faXmark,
|
|
|
|
bgClassName: 'bg-destroy-80',
|
|
|
|
iconClassName:
|
|
|
|
'text-destroy-20 group-hover:text-destroy-10 hover:text-destroy-10',
|
|
|
|
}}
|
|
|
|
className="hover:border-destroy-40"
|
|
|
|
>
|
|
|
|
Close
|
|
|
|
</ActionButton>
|
|
|
|
</AppHeader>
|
|
|
|
<div className="mt-24 max-w-5xl mx-auto">
|
|
|
|
<h1 className="text-4xl font-bold">User Settings</h1>
|
|
|
|
{(window as any).__TAURI__ && (
|
|
|
|
<SettingsSection
|
|
|
|
title="Default Directory"
|
|
|
|
description="Where newly-created projects are saved on your local computer"
|
|
|
|
>
|
|
|
|
<div className="w-full flex gap-4 p-1 rounded border border-chalkboard-30">
|
|
|
|
<input
|
|
|
|
className="flex-1 px-2 bg-transparent"
|
|
|
|
value={defaultDir.dir}
|
|
|
|
onChange={(e) =>
|
|
|
|
setDefaultDir({
|
2023-07-21 12:48:23 -04:00
|
|
|
base: ogDefaultDir.base,
|
2023-07-13 07:22:08 -04:00
|
|
|
dir: e.target.value,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
<ActionButton
|
2023-07-27 18:59:40 -04:00
|
|
|
Element="button"
|
2023-07-13 07:22:08 -04:00
|
|
|
className="bg-chalkboard-100 hover:bg-chalkboard-90 text-chalkboard-10 border-chalkboard-100 hover:border-chalkboard-70"
|
|
|
|
onClick={handleDirectorySelection}
|
|
|
|
icon={{
|
|
|
|
icon: faFolder,
|
|
|
|
bgClassName:
|
|
|
|
'bg-liquid-20 group-hover:bg-liquid-10 hover:bg-liquid-10',
|
|
|
|
iconClassName:
|
|
|
|
'text-liquid-90 group-hover:text-liquid-90 hover:text-liquid-90',
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
Choose a folder
|
|
|
|
</ActionButton>
|
|
|
|
</div>
|
|
|
|
</SettingsSection>
|
|
|
|
)}
|
|
|
|
<SettingsSection
|
|
|
|
title="Default Project Name"
|
|
|
|
description="Name template for new projects. Use $n to include an incrementing index"
|
|
|
|
>
|
|
|
|
<input
|
|
|
|
className="block w-full px-3 py-1 border border-chalkboard-30 bg-transparent"
|
|
|
|
value={defaultProjectName}
|
|
|
|
onChange={(e) => setDefaultProjectName(e.target.value)}
|
|
|
|
/>
|
|
|
|
</SettingsSection>
|
2023-07-21 12:48:23 -04:00
|
|
|
<SettingsSection
|
|
|
|
title="Unit System"
|
|
|
|
description="Which unit system to use by default"
|
|
|
|
>
|
|
|
|
<Toggle
|
|
|
|
offLabel="Imperial"
|
|
|
|
onLabel="Metric"
|
|
|
|
name="settings-units"
|
|
|
|
checked={defaultUnitSystem === 'metric'}
|
|
|
|
onChange={(e) =>
|
|
|
|
setDefaultUnitSystem(e.target.checked ? 'metric' : 'imperial')
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</SettingsSection>
|
|
|
|
<SettingsSection
|
|
|
|
title="Base Unit"
|
|
|
|
description="Which base unit to use in dimensions by default"
|
|
|
|
>
|
|
|
|
<select
|
|
|
|
id="base-unit"
|
|
|
|
className="block w-full px-3 py-1 border border-chalkboard-30 bg-transparent"
|
|
|
|
value={defaultBaseUnit}
|
|
|
|
onChange={(e) => setDefaultBaseUnit(e.target.value)}
|
|
|
|
>
|
|
|
|
{baseUnits[defaultUnitSystem].map((unit) => (
|
|
|
|
<option key={unit} value={unit}>
|
|
|
|
{unit}
|
|
|
|
</option>
|
|
|
|
))}
|
|
|
|
</select>
|
|
|
|
</SettingsSection>
|
2023-07-21 16:53:06 +10:00
|
|
|
<SettingsSection
|
|
|
|
title="Debug Panel"
|
|
|
|
description="Show the debug panel in the editor"
|
|
|
|
>
|
2023-07-21 12:48:23 -04:00
|
|
|
<Toggle
|
|
|
|
name="settings-debug-panel"
|
2023-07-21 16:53:06 +10:00
|
|
|
checked={debugPanel}
|
|
|
|
onChange={(e) => setDebugPanel(e.target.checked)}
|
|
|
|
/>
|
|
|
|
</SettingsSection>
|
2023-07-25 10:40:26 -04:00
|
|
|
<SettingsSection
|
|
|
|
title="Onboarding"
|
|
|
|
description="Replay the onboarding process"
|
|
|
|
>
|
|
|
|
<ActionButton
|
|
|
|
onClick={() => {
|
|
|
|
saveOnboardingStatus('')
|
|
|
|
navigate('/')
|
|
|
|
}}
|
|
|
|
icon={{ icon: faArrowRotateBack }}
|
|
|
|
>
|
|
|
|
Replay Onboarding
|
|
|
|
</ActionButton>
|
|
|
|
</SettingsSection>
|
2023-07-13 07:22:08 -04:00
|
|
|
<ActionButton
|
|
|
|
className="hover:border-succeed-50"
|
|
|
|
onClick={handleSaveClick}
|
|
|
|
icon={{
|
|
|
|
icon: faCheck,
|
|
|
|
bgClassName:
|
|
|
|
'bg-succeed-80 group-hover:bg-succeed-70 hover:bg-succeed-70',
|
|
|
|
iconClassName:
|
|
|
|
'text-succeed-20 group-hover:text-succeed-10 hover:text-succeed-10',
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
Save Settings
|
|
|
|
</ActionButton>
|
|
|
|
</div>
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
interface SettingsSectionProps extends React.PropsWithChildren {
|
|
|
|
title: string
|
|
|
|
description?: string
|
|
|
|
}
|
|
|
|
|
2023-07-25 10:40:26 -04:00
|
|
|
export function SettingsSection({
|
2023-07-13 07:22:08 -04:00
|
|
|
title,
|
|
|
|
description,
|
|
|
|
children,
|
|
|
|
}: SettingsSectionProps) {
|
|
|
|
return (
|
|
|
|
<section className="my-8 first-of-type:mt-16 last-of-type:mb-16 flex gap-12 items-start">
|
|
|
|
<div className="w-80">
|
|
|
|
<h2 className="text-2xl">{title}</h2>
|
|
|
|
<p className="mt-2 text-sm">{description}</p>
|
|
|
|
</div>
|
2023-07-21 12:48:23 -04:00
|
|
|
<div>{children}</div>
|
2023-07-13 07:22:08 -04:00
|
|
|
</section>
|
|
|
|
)
|
|
|
|
}
|