mirror of
https://github.com/aljazceru/landscape-template.git
synced 2025-12-27 11:14:33 +01:00
feat: add excerpt column to db, add preveiw© story to text editor
This commit is contained in:
@@ -81,9 +81,6 @@ const PostBase = interfaceType({
|
||||
t.nonNull.int('id');
|
||||
t.nonNull.string('title');
|
||||
t.nonNull.date('createdAt');
|
||||
t.nonNull.string('excerpt', {
|
||||
resolve: (parent) => parent.body.slice(0, 150)
|
||||
});
|
||||
t.nonNull.string('body');
|
||||
t.nonNull.int('votes_count');
|
||||
},
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- Added the required column `excerpt` to the `Question` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `excerpt` to the `Story` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Question" ADD COLUMN "excerpt" TEXT NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Story" ADD COLUMN "excerpt" TEXT NOT NULL;
|
||||
@@ -100,6 +100,7 @@ model Story {
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
body String
|
||||
excerpt String
|
||||
cover_image String
|
||||
votes_count Int @default(0)
|
||||
|
||||
@@ -120,6 +121,7 @@ model Question {
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
body String
|
||||
excerpt String
|
||||
votes_count Int @default(0)
|
||||
|
||||
topic Topic @relation(fields: [topic_id], references: [id])
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import { FaCopy } from 'react-icons/fa';
|
||||
import Button from 'src/Components/Button/Button';
|
||||
import useCopyToClipboard from 'src/utils/hooks/useCopyToClipboard';
|
||||
import { WithModals } from 'src/utils/storybook/decorators';
|
||||
|
||||
import TextEditor from './TextEditor';
|
||||
@@ -50,36 +54,58 @@ const PreviewTemplate: ComponentStory<typeof TextEditor> = (args) => {
|
||||
content: ""
|
||||
}
|
||||
});
|
||||
const [mode, setMode] = useState(1); // 1 = editing, 0 = preview
|
||||
const [copied, setCopied] = useState(false)
|
||||
|
||||
const md = methods.watch('content')
|
||||
console.log(md);
|
||||
const copy = useCopyToClipboard();
|
||||
const copyToClipboard = () => {
|
||||
copy(methods.getValues('content'));
|
||||
setCopied(true);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
let timer: NodeJS.Timer;
|
||||
if (copied) {
|
||||
timer = setTimeout(() => setCopied(false), 1000)
|
||||
}
|
||||
return () => {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
}, [copied])
|
||||
|
||||
|
||||
return <FormProvider {...methods}>
|
||||
<div className="max-w-[80ch]">
|
||||
<TextEditor {...args} />
|
||||
<div
|
||||
className="mt-32 bg-white p-32 border rounded-12 remirror-theme"
|
||||
dangerouslySetInnerHTML={{ __html: md }}
|
||||
>
|
||||
<div className="flex gap-16 items-start">
|
||||
<div className={`${mode === 0 && 'hidden'} grow`}>
|
||||
<TextEditor {...args} />
|
||||
</div>
|
||||
<div className={`${mode === 1 && 'hidden'} grow`}>
|
||||
<div className="remirror-theme p-16 border bg-white rounded-16">
|
||||
<div dangerouslySetInnerHTML={{
|
||||
__html: methods.getValues('content')
|
||||
}}>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Button onClick={() => setMode(v => 1 - v)}>
|
||||
{mode === 1 ? "Preview" : "Edit"}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Button className='mt-36' onClick={copyToClipboard}>
|
||||
<FaCopy /> Copy to clipboard
|
||||
</Button>
|
||||
</div>
|
||||
</FormProvider>
|
||||
}
|
||||
|
||||
export const WithPreview = PreviewTemplate.bind({});
|
||||
WithPreview.args = {
|
||||
export const CanCopy = PreviewTemplate.bind({});
|
||||
CanCopy.args = {
|
||||
placeholder: "Start writing something in markdown",
|
||||
initialContent: `
|
||||
## heading2
|
||||
|
||||
#### heading4
|
||||
|
||||
###### heading6
|
||||
|
||||
some text with **bold**, _italic,_ underline, [www.link.com](//www.link.com)
|
||||
|
||||
\`code line goes here\`
|
||||
<h2 style="">Hello there</h2><p style="">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<br></p><h2 style="">How are you doing ??</h2><p style="">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. <strong>Excepteur</strong> sint <strong>occaecat</strong> cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<br><br><br></p><h3 style="">Subheading</h3><p style="">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.<br>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
|
||||
`
|
||||
}
|
||||
@@ -4,3 +4,4 @@ export * from "./usePressHolder";
|
||||
export * from "./useInfiniteQuery";
|
||||
export * from "./useReachedBottom";
|
||||
export * from "./useAutoResizableTextArea";
|
||||
export * from "./useCopyToClipboard";
|
||||
|
||||
26
src/utils/hooks/useCopyToClipboard.ts
Normal file
26
src/utils/hooks/useCopyToClipboard.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
type CopiedValue = string | null
|
||||
type CopyFn = (text: string) => Promise<boolean> // Return success
|
||||
|
||||
function useCopyToClipboard(): CopyFn {
|
||||
|
||||
const copy: CopyFn = async text => {
|
||||
if (!navigator?.clipboard) {
|
||||
console.warn('Clipboard not supported')
|
||||
return false
|
||||
}
|
||||
|
||||
// Try to save to clipboard then save it in the state if worked
|
||||
try {
|
||||
await navigator.clipboard.writeText(text)
|
||||
return true
|
||||
} catch (error) {
|
||||
console.warn('Copy failed', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return copy
|
||||
}
|
||||
|
||||
export default useCopyToClipboard
|
||||
Reference in New Issue
Block a user