mirror of
https://github.com/aljazceru/landscape-template.git
synced 2026-01-27 10:14:45 +01:00
fix: make padding 16px on mobile for create-story-form, make drafts container start after the edit/preview bar
This commit is contained in:
@@ -13,13 +13,14 @@ import { useReduxEffect } from 'src/utils/hooks/useReduxEffect';
|
||||
import { IStoryFormInputs } from '../../CreateStoryPage/CreateStoryPage';
|
||||
|
||||
interface Props {
|
||||
id?: string;
|
||||
type: Post_Type,
|
||||
onDraftLoad?: () => void,
|
||||
}
|
||||
|
||||
const CONFIRM_DELETE_STORY = createAction<{ confirmed?: boolean, id: number }>('DELETE_STORY_CONFIRMED')({ id: -1 })
|
||||
|
||||
export default function DraftsContainer({ type, onDraftLoad }: Props) {
|
||||
export default function DraftsContainer({ id, type, onDraftLoad }: Props) {
|
||||
|
||||
|
||||
const myDraftsQuery = useGetMyDraftsQuery({ variables: { type } });
|
||||
@@ -92,7 +93,7 @@ export default function DraftsContainer({ type, onDraftLoad }: Props) {
|
||||
|
||||
return (
|
||||
|
||||
<>
|
||||
<div id={id}>
|
||||
{(!myDraftsQuery.loading && myDraftsQuery.data?.getMyDrafts && myDraftsQuery.data.getMyDrafts.length > 0) &&
|
||||
<div className="bg-white border-2 border-gray-200 rounded-16 p-16">
|
||||
<p className="text-body2 font-bolder mb-16">Saved Drafts</p>
|
||||
@@ -114,6 +115,6 @@ export default function DraftsContainer({ type, onDraftLoad }: Props) {
|
||||
</ul>
|
||||
</div>}
|
||||
{loading && <LoadingPage />}
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,12 +2,18 @@ import React, { forwardRef } from 'react'
|
||||
import { useFormContext } from 'react-hook-form'
|
||||
import { IStoryFormInputs } from '../../CreateStoryPage/CreateStoryPage';
|
||||
|
||||
const ErrorsContainer = forwardRef<HTMLDivElement>((props, ref) => {
|
||||
interface Props {
|
||||
id?: string;
|
||||
}
|
||||
|
||||
const ErrorsContainer = forwardRef<HTMLDivElement, Props>((props, ref) => {
|
||||
|
||||
const { formState: { isValid, isSubmitted, errors } } = useFormContext<IStoryFormInputs>();
|
||||
|
||||
const hasErrors = Object.values(errors).length > 0
|
||||
|
||||
return (
|
||||
<div ref={ref}>
|
||||
hasErrors ? <div id={props.id} ref={ref}>
|
||||
{(!isValid && isSubmitted) && <ul className='bg-red-50 p-8 pl-24 border-l-4 rounded-8 border-red-600 list-disc text-body4 text-medium'>
|
||||
{errors.title && <li className="input-error text-body5 text-medium">
|
||||
{errors.title.message}
|
||||
@@ -23,6 +29,8 @@ const ErrorsContainer = forwardRef<HTMLDivElement>((props, ref) => {
|
||||
</li>}
|
||||
</ul>}
|
||||
</div>
|
||||
:
|
||||
null
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
@@ -104,90 +104,93 @@ export default function StoryForm(props: Props) {
|
||||
|
||||
|
||||
return (
|
||||
<form
|
||||
onSubmit={clickSubmit(true)}
|
||||
>
|
||||
<div className="flex gap-16 mb-24">
|
||||
<>
|
||||
<div id='preview-switch' className="flex gap-16">
|
||||
<button type='button' className={`rounded-8 px-16 py-8 ${editMode ? 'bg-primary-100 text-primary-700' : "text-gray-500"} active:scale-95 transition-transform`} onClick={() => setEditMode(true)}>Edit</button>
|
||||
<button type='button' className={`rounded-8 px-16 py-8 ${!editMode ? 'bg-primary-100 text-primary-700' : "text-gray-500"} active:scale-95 transition-transform`} onClick={clickPreview}>Preview</button>
|
||||
</div>
|
||||
{editMode && <>
|
||||
<div
|
||||
className='bg-white border-2 border-gray-200 rounded-16 overflow-hidden'>
|
||||
<div className="p-32">
|
||||
<Controller
|
||||
control={control}
|
||||
name="cover_image"
|
||||
render={({ field: { onChange, value, onBlur, ref } }) => (
|
||||
<FilesInput
|
||||
ref={ref}
|
||||
value={value}
|
||||
onBlur={onBlur}
|
||||
onChange={onChange}
|
||||
uploadText='Add a cover image'
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
|
||||
|
||||
<div className="mt-16 relative">
|
||||
<textarea
|
||||
rows={1}
|
||||
autoFocus
|
||||
className="p-0 text-[42px] leading-[58px] border-0 w-full max-w-full resize-none
|
||||
focus:border-0 focus:outline-none focus:ring-0 font-bolder placeholder:!text-gray-400"
|
||||
placeholder='New story title here...'
|
||||
{...titleRegisteration}
|
||||
ref={e => {
|
||||
registerTitleRef(e);
|
||||
titleInputRef.current = e;
|
||||
}}
|
||||
onInput={() => {
|
||||
if (!titleInputRef.current) return;
|
||||
titleInputRef.current.style.height = "auto";
|
||||
titleInputRef.current.style.height = (titleInputRef.current.scrollHeight) + "px";
|
||||
}}
|
||||
<form
|
||||
id='form'
|
||||
onSubmit={clickSubmit(true)}
|
||||
>
|
||||
{editMode && <>
|
||||
<div
|
||||
className='bg-white border-2 border-gray-200 rounded-16 overflow-hidden'>
|
||||
<div className="p-16 md:p-32">
|
||||
<Controller
|
||||
control={control}
|
||||
name="cover_image"
|
||||
render={({ field: { onChange, value, onBlur, ref } }) => (
|
||||
<FilesInput
|
||||
ref={ref}
|
||||
value={value}
|
||||
onBlur={onBlur}
|
||||
onChange={onChange}
|
||||
uploadText='Add a cover image'
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<TagsInput
|
||||
placeholder="Add up to 5 popular tags..."
|
||||
classes={{ container: 'mt-16' }}
|
||||
|
||||
|
||||
<div className="mt-16 relative">
|
||||
<textarea
|
||||
rows={1}
|
||||
autoFocus
|
||||
className="p-0 text-[42px] leading-[58px] border-0 w-full max-w-full resize-none
|
||||
focus:border-0 focus:outline-none focus:ring-0 font-bolder placeholder:!text-gray-400"
|
||||
placeholder='New story title here...'
|
||||
{...titleRegisteration}
|
||||
ref={e => {
|
||||
registerTitleRef(e);
|
||||
titleInputRef.current = e;
|
||||
}}
|
||||
onInput={() => {
|
||||
if (!titleInputRef.current) return;
|
||||
titleInputRef.current.style.height = "auto";
|
||||
titleInputRef.current.style.height = (titleInputRef.current.scrollHeight) + "px";
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<TagsInput
|
||||
placeholder="Add up to 5 popular tags..."
|
||||
classes={{ container: 'mt-16' }}
|
||||
/>
|
||||
|
||||
</div>
|
||||
<ContentEditor
|
||||
key={postId}
|
||||
initialContent={() => getValues().body}
|
||||
placeholder="Write your story content here..."
|
||||
name="body"
|
||||
/>
|
||||
|
||||
</div>
|
||||
<ContentEditor
|
||||
key={postId}
|
||||
initialContent={() => getValues().body}
|
||||
placeholder="Write your story content here..."
|
||||
name="body"
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
</>}
|
||||
{!editMode && <PreviewPostCard post={{ ...getValues(), cover_image: getValues().cover_image[0] }} />}
|
||||
<div className="flex gap-16 mt-32">
|
||||
<Button
|
||||
type='submit'
|
||||
color="primary"
|
||||
disabled={loading}
|
||||
>
|
||||
{props.isUpdating ?
|
||||
"Update" :
|
||||
"Publish"
|
||||
}
|
||||
</Button>
|
||||
{!props.isPublished &&
|
||||
</>}
|
||||
{!editMode && <PreviewPostCard post={{ ...getValues(), cover_image: getValues().cover_image[0] }} />}
|
||||
<div className="flex gap-16 mt-32">
|
||||
<Button
|
||||
color="gray"
|
||||
type='submit'
|
||||
color="primary"
|
||||
disabled={loading}
|
||||
onClick={clickSubmit(false)}
|
||||
>
|
||||
Save as Draft
|
||||
</Button>}
|
||||
</div>
|
||||
</form>
|
||||
{props.isUpdating ?
|
||||
"Update" :
|
||||
"Publish"
|
||||
}
|
||||
</Button>
|
||||
{!props.isPublished &&
|
||||
<Button
|
||||
color="gray"
|
||||
disabled={loading}
|
||||
onClick={clickSubmit(false)}
|
||||
>
|
||||
Save as Draft
|
||||
</Button>}
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -87,22 +87,18 @@ export default function CreateStoryPage() {
|
||||
<FormProvider {...formMethods}>
|
||||
<div className={styles.grid}>
|
||||
|
||||
<div id="form">
|
||||
<StoryForm
|
||||
key={formKey}
|
||||
isPublished={!!story?.is_published}
|
||||
isUpdating={!!story?.id}
|
||||
onSuccess={() => resetForm()}
|
||||
onValidationError={() => errorsContainerRef.current.scrollIntoView({ behavior: 'smooth', block: "center" })}
|
||||
/>
|
||||
</div>
|
||||
<StoryForm
|
||||
key={formKey}
|
||||
isPublished={!!story?.is_published}
|
||||
isUpdating={!!story?.id}
|
||||
onSuccess={() => resetForm()}
|
||||
onValidationError={() => errorsContainerRef.current.scrollIntoView({ behavior: 'smooth', block: "center" })}
|
||||
/>
|
||||
|
||||
<ErrorsContainer id='errors' ref={errorsContainerRef} />
|
||||
|
||||
<DraftsContainer id='drafts' type={Post_Type.Story} onDraftLoad={resetForm} />
|
||||
|
||||
<div id="errors">
|
||||
<ErrorsContainer ref={errorsContainerRef} />
|
||||
</div>
|
||||
<div id="drafts">
|
||||
<DraftsContainer type={Post_Type.Story} onDraftLoad={resetForm} />
|
||||
</div>
|
||||
</div>
|
||||
</FormProvider>
|
||||
)
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
@import "/src/styles/mixins/index.scss";
|
||||
|
||||
.grid {
|
||||
--gap: 32px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 32px;
|
||||
|
||||
column-gap: var(--gap);
|
||||
row-gap: var(--gap);
|
||||
|
||||
& > * {
|
||||
min-width: 0;
|
||||
@@ -11,26 +14,42 @@
|
||||
|
||||
grid-template-areas:
|
||||
"errors"
|
||||
"preview-switch"
|
||||
"form"
|
||||
"drafts";
|
||||
|
||||
:global {
|
||||
#errors {
|
||||
grid-area: errors;
|
||||
#preview-switch {
|
||||
grid-area: preview-switch;
|
||||
}
|
||||
#form {
|
||||
grid-area: form;
|
||||
}
|
||||
#errors {
|
||||
grid-area: errors;
|
||||
}
|
||||
#drafts {
|
||||
grid-area: drafts;
|
||||
}
|
||||
}
|
||||
|
||||
@include gt-xl {
|
||||
row-gap: unset;
|
||||
|
||||
grid-template-columns: 1fr calc(min(326px, 25%));
|
||||
grid-template-areas:
|
||||
"preview-switch preview-switch"
|
||||
"form errors"
|
||||
"form drafts"
|
||||
"form .";
|
||||
|
||||
:global {
|
||||
#preview-switch {
|
||||
margin-bottom: var(--gap);
|
||||
}
|
||||
#errors {
|
||||
margin-bottom: var(--gap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user