Home page touch-ups (#2135)
* Save part images when navigating home * Load part images in project cards if available * Polish home page * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * Merge branch 'main' into franknoirot/project-images * Mostly restored link + form functionality * Working cards with images * Comment out project image stuff * Little style tweaks * Remove unused imports * More minor styling tweaks * Merge branch 'main' into franknoirot/project-images * Was using the wrong imported `Project` type * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * Revert any docs changes * Revert wasm-lib divergences * Move ProjectCard into its component folder * Remove unused hook useSaveVideoFrame * Remove "hideOnLevel" config from theme setting --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -4,16 +4,15 @@ import {
|
||||
getNextProjectIndex,
|
||||
interpolateProjectNameWithIndex,
|
||||
doesProjectNameNeedInterpolated,
|
||||
} from '../lib/tauriFS'
|
||||
import { ActionButton } from '../components/ActionButton'
|
||||
import { faArrowDown, faPlus } from '@fortawesome/free-solid-svg-icons'
|
||||
} from 'lib/tauriFS'
|
||||
import { ActionButton } from 'components/ActionButton'
|
||||
import { toast } from 'react-hot-toast'
|
||||
import { AppHeader } from '../components/AppHeader'
|
||||
import ProjectCard from '../components/ProjectCard'
|
||||
import { AppHeader } from 'components/AppHeader'
|
||||
import ProjectCard from 'components/ProjectCard/ProjectCard'
|
||||
import { useLoaderData, useNavigate, useSearchParams } from 'react-router-dom'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { type HomeLoaderData } from 'lib/types'
|
||||
import Loading from '../components/Loading'
|
||||
import Loading from 'components/Loading'
|
||||
import { useMachine } from '@xstate/react'
|
||||
import { homeMachine } from '../machines/homeMachine'
|
||||
import { ContextFrom, EventFrom } from 'xstate'
|
||||
@ -187,9 +186,11 @@ const Home = () => {
|
||||
new FormData(e.target as HTMLFormElement)
|
||||
)
|
||||
|
||||
send('Rename project', {
|
||||
data: { oldName: project.name, newName: newProjectName },
|
||||
})
|
||||
if (newProjectName !== project.name) {
|
||||
send('Rename project', {
|
||||
data: { oldName: project.name, newName: newProjectName },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDeleteProject(project: Project) {
|
||||
@ -199,71 +200,93 @@ const Home = () => {
|
||||
return (
|
||||
<div className="relative flex flex-col h-screen overflow-hidden">
|
||||
<AppHeader showToolbar={false} />
|
||||
<div className="w-full max-w-5xl px-4 mx-auto my-24 overflow-y-auto lg:px-0">
|
||||
<section className="flex justify-between">
|
||||
<h1 className="text-3xl font-bold">Your Projects</h1>
|
||||
<div className="flex gap-2 items-center">
|
||||
<small>Sort by</small>
|
||||
<ActionButton
|
||||
Element="button"
|
||||
className={
|
||||
'text-sm ' +
|
||||
(!sort.includes('name')
|
||||
? 'text-chalkboard-80 dark:text-chalkboard-40'
|
||||
: '')
|
||||
}
|
||||
onClick={() => setSearchParams(getNextSearchParams(sort, 'name'))}
|
||||
iconStart={{
|
||||
icon: getSortIcon(sort, 'name'),
|
||||
className: 'p-1.5',
|
||||
iconClassName: !sort.includes('name')
|
||||
? '!text-chalkboard-40'
|
||||
: '',
|
||||
size: 'sm',
|
||||
}}
|
||||
>
|
||||
Name
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
Element="button"
|
||||
className={
|
||||
'text-sm ' +
|
||||
(!isSortByModified
|
||||
? 'text-chalkboard-80 dark:text-chalkboard-40'
|
||||
: '')
|
||||
}
|
||||
onClick={() =>
|
||||
setSearchParams(getNextSearchParams(sort, 'modified'))
|
||||
}
|
||||
iconStart={{
|
||||
icon: sort ? getSortIcon(sort, 'modified') : faArrowDown,
|
||||
className: 'p-1.5',
|
||||
iconClassName: !isSortByModified ? '!text-chalkboard-40' : '',
|
||||
size: 'sm',
|
||||
}}
|
||||
>
|
||||
Last Modified
|
||||
</ActionButton>
|
||||
<div className="w-full flex flex-col overflow-hidden max-w-5xl px-4 mx-auto mt-24 lg:px-2">
|
||||
<section>
|
||||
<div className="flex justify-between items-baseline select-none">
|
||||
<div className="flex gap-8 items-baseline">
|
||||
<h1 className="text-3xl font-bold">Your Projects</h1>
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => send('Create project')}
|
||||
className="group !bg-primary !text-chalkboard-10 !border-primary hover:shadow-inner hover:hue-rotate-15"
|
||||
iconStart={{
|
||||
icon: 'plus',
|
||||
bgClassName: '!bg-transparent rounded-sm',
|
||||
iconClassName:
|
||||
'!text-chalkboard-10 transition-transform group-active:rotate-90',
|
||||
}}
|
||||
data-testid="home-new-file"
|
||||
>
|
||||
New project
|
||||
</ActionButton>
|
||||
</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
<small>Sort by</small>
|
||||
<ActionButton
|
||||
Element="button"
|
||||
className={
|
||||
'text-xs border-primary/10 ' +
|
||||
(!sort.includes('name')
|
||||
? 'text-chalkboard-80 dark:text-chalkboard-40'
|
||||
: '')
|
||||
}
|
||||
onClick={() =>
|
||||
setSearchParams(getNextSearchParams(sort, 'name'))
|
||||
}
|
||||
iconStart={{
|
||||
icon: getSortIcon(sort, 'name'),
|
||||
bgClassName: 'bg-transparent',
|
||||
iconClassName: !sort.includes('name')
|
||||
? '!text-chalkboard-90 dark:!text-chalkboard-30'
|
||||
: '',
|
||||
}}
|
||||
>
|
||||
Name
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
Element="button"
|
||||
className={
|
||||
'text-xs border-primary/10 ' +
|
||||
(!isSortByModified
|
||||
? 'text-chalkboard-80 dark:text-chalkboard-40'
|
||||
: '')
|
||||
}
|
||||
onClick={() =>
|
||||
setSearchParams(getNextSearchParams(sort, 'modified'))
|
||||
}
|
||||
iconStart={{
|
||||
icon: sort ? getSortIcon(sort, 'modified') : 'arrowDown',
|
||||
bgClassName: 'bg-transparent',
|
||||
iconClassName: !isSortByModified
|
||||
? '!text-chalkboard-90 dark:!text-chalkboard-30'
|
||||
: '',
|
||||
}}
|
||||
>
|
||||
Last Modified
|
||||
</ActionButton>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section data-testid="home-section">
|
||||
<p className="my-4 text-sm text-chalkboard-80 dark:text-chalkboard-30">
|
||||
Loaded from{' '}
|
||||
<span className="text-chalkboard-90 dark:text-chalkboard-20">
|
||||
<Link
|
||||
to="settings?tab=user#projectDirectory"
|
||||
className="text-chalkboard-90 dark:text-chalkboard-20 underline underline-offset-2"
|
||||
>
|
||||
{settings.app.projectDirectory.current}
|
||||
</span>
|
||||
.{' '}
|
||||
<Link to="settings" className="underline underline-offset-2">
|
||||
Edit in settings
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</section>
|
||||
<section
|
||||
data-testid="home-section"
|
||||
className="flex-1 overflow-y-auto pr-2 pb-24"
|
||||
>
|
||||
{state.matches('Reading projects') ? (
|
||||
<Loading>Loading your Projects...</Loading>
|
||||
) : (
|
||||
<>
|
||||
{projects.length > 0 ? (
|
||||
<ul className="grid w-full grid-cols-4 gap-4 my-8">
|
||||
<ul className="grid w-full grid-cols-4 gap-4">
|
||||
{projects.sort(getSortFunction(sort)).map((project) => (
|
||||
<ProjectCard
|
||||
key={project.name}
|
||||
@ -278,14 +301,6 @@ const Home = () => {
|
||||
No Projects found, ready to make your first one?
|
||||
</p>
|
||||
)}
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => send('Create project')}
|
||||
iconStart={{ icon: faPlus, iconClassName: 'p-1 w-4' }}
|
||||
data-testid="home-new-file"
|
||||
>
|
||||
New project
|
||||
</ActionButton>
|
||||
</>
|
||||
)}
|
||||
</section>
|
||||
|
Reference in New Issue
Block a user