Normal tooltip | Fixed quill redactor
This commit is contained in:
parent
6d6babc305
commit
6a22797610
31
enshi/package-lock.json
generated
31
enshi/package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "enshi",
|
"name": "enshi",
|
||||||
"version": "0.1.7",
|
"version": "0.1.8",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "enshi",
|
"name": "enshi",
|
||||||
"version": "0.1.7",
|
"version": "0.1.8",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@radix-ui/react-dialog": "^1.1.2",
|
"@radix-ui/react-dialog": "^1.1.2",
|
||||||
"@radix-ui/react-form": "^0.1.0",
|
"@radix-ui/react-form": "^0.1.0",
|
||||||
@ -18,6 +18,7 @@
|
|||||||
"@radix-ui/themes": "^3.1.3",
|
"@radix-ui/themes": "^3.1.3",
|
||||||
"@tanstack/react-query": "^5.55.0",
|
"@tanstack/react-query": "^5.55.0",
|
||||||
"@tanstack/react-query-devtools": "^5.61.0",
|
"@tanstack/react-query-devtools": "^5.61.0",
|
||||||
|
"@types/quill": "^2.0.14",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
"html-react-parser": "^5.1.16",
|
"html-react-parser": "^5.1.16",
|
||||||
"i18n": "^0.15.1",
|
"i18n": "^0.15.1",
|
||||||
@ -28,7 +29,7 @@
|
|||||||
"jotai": "^2.9.3",
|
"jotai": "^2.9.3",
|
||||||
"jotai-immer": "^0.4.1",
|
"jotai-immer": "^0.4.1",
|
||||||
"primereact": "^10.8.2",
|
"primereact": "^10.8.2",
|
||||||
"quill": "^2.0.2",
|
"quill": "^2.0.3",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-i18next": "^15.0.1",
|
"react-i18next": "^15.0.1",
|
||||||
@ -3422,12 +3423,13 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/quill": {
|
"node_modules/@types/quill": {
|
||||||
"version": "1.3.10",
|
"version": "2.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/@types/quill/-/quill-1.3.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/quill/-/quill-2.0.14.tgz",
|
||||||
"integrity": "sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==",
|
"integrity": "sha512-zvoXCRnc2Dl8g+7/9VSAmRWPN6oH+MVhTPizmCR+GJCITplZ5VRVzMs4+a/nOE3yzNwEZqylJJrMB07bwbM1/g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"parchment": "^1.1.2"
|
"parchment": "^1.1.2",
|
||||||
|
"quill-delta": "^5.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/quill/node_modules/parchment": {
|
"node_modules/@types/quill/node_modules/parchment": {
|
||||||
@ -6409,9 +6411,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/quill": {
|
"node_modules/quill": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/quill/-/quill-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/quill/-/quill-2.0.3.tgz",
|
||||||
"integrity": "sha512-QfazNrhMakEdRG57IoYFwffUIr04LWJxbS/ZkidRFXYCQt63c1gK6Z7IHUXMx/Vh25WgPBU42oBaNzQ0K1R/xw==",
|
"integrity": "sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"eventemitter3": "^5.0.1",
|
"eventemitter3": "^5.0.1",
|
||||||
@ -6511,6 +6513,15 @@
|
|||||||
"react-dom": "^16 || ^17 || ^18"
|
"react-dom": "^16 || ^17 || ^18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-quill/node_modules/@types/quill": {
|
||||||
|
"version": "1.3.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/quill/-/quill-1.3.10.tgz",
|
||||||
|
"integrity": "sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"parchment": "^1.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-quill/node_modules/eventemitter3": {
|
"node_modules/react-quill/node_modules/eventemitter3": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
"@radix-ui/themes": "^3.1.3",
|
"@radix-ui/themes": "^3.1.3",
|
||||||
"@tanstack/react-query": "^5.55.0",
|
"@tanstack/react-query": "^5.55.0",
|
||||||
"@tanstack/react-query-devtools": "^5.61.0",
|
"@tanstack/react-query-devtools": "^5.61.0",
|
||||||
|
"@types/quill": "^2.0.14",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
"html-react-parser": "^5.1.16",
|
"html-react-parser": "^5.1.16",
|
||||||
"i18n": "^0.15.1",
|
"i18n": "^0.15.1",
|
||||||
@ -31,7 +32,7 @@
|
|||||||
"jotai": "^2.9.3",
|
"jotai": "^2.9.3",
|
||||||
"jotai-immer": "^0.4.1",
|
"jotai-immer": "^0.4.1",
|
||||||
"primereact": "^10.8.2",
|
"primereact": "^10.8.2",
|
||||||
"quill": "^2.0.2",
|
"quill": "^2.0.3",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-i18next": "^15.0.1",
|
"react-i18next": "^15.0.1",
|
||||||
|
|||||||
@ -6,3 +6,8 @@ export type GetRandomPostsRow = {
|
|||||||
// created_at: Date;
|
// created_at: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type TPostData = {
|
||||||
|
title: string;
|
||||||
|
content: string;
|
||||||
|
};
|
||||||
@ -426,6 +426,16 @@
|
|||||||
content: '';
|
content: '';
|
||||||
display: table;
|
display: table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ql-toolbar {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ql-container {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.ql-snow.ql-toolbar button,
|
.ql-snow.ql-toolbar button,
|
||||||
.ql-snow .ql-toolbar button {
|
.ql-snow .ql-toolbar button {
|
||||||
background: none;
|
background: none;
|
||||||
|
|||||||
@ -1,23 +1,28 @@
|
|||||||
import { Theme, ThemePanel } from "@radix-ui/themes";
|
import { Theme } from "@radix-ui/themes";
|
||||||
import "@radix-ui/themes/styles.css";
|
import "@radix-ui/themes/styles.css";
|
||||||
import { QueryClientProvider } from "@tanstack/react-query";
|
import { QueryClientProvider } from "@tanstack/react-query";
|
||||||
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
||||||
import "axios";
|
import "axios";
|
||||||
|
import { useAtomValue } from "jotai";
|
||||||
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
||||||
import queryClient from "./api/QueryClient/QueryClient";
|
import queryClient from "./api/QueryClient/QueryClient";
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
|
import { themeAtom } from "./AtomStore/AtomStore";
|
||||||
import ToastProvider from "./Components/ToastProvider/ToastProvider";
|
import ToastProvider from "./Components/ToastProvider/ToastProvider";
|
||||||
import { routes } from "./routes/routes";
|
import { routes } from "./routes/routes";
|
||||||
|
|
||||||
const router = createBrowserRouter(routes);
|
const router = createBrowserRouter(routes);
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
|
|
||||||
|
const theme = useAtomValue(themeAtom);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Theme className="h-fit" accentColor="sky" grayColor="slate" appearance="dark">
|
<Theme className="h-fit" accentColor="sky" grayColor="slate" appearance={theme}>
|
||||||
<ToastProvider>
|
<ToastProvider>
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<RouterProvider router={router} />
|
<RouterProvider router={router} />
|
||||||
<ThemePanel />
|
{/* <ThemePanel /> */}
|
||||||
<ReactQueryDevtools/>
|
<ReactQueryDevtools/>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
</ToastProvider>
|
</ToastProvider>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { atom } from "jotai";
|
import { atom } from "jotai";
|
||||||
import { atomWithStorage } from "jotai/utils";
|
import { atomWithStorage } from "jotai/utils";
|
||||||
|
import { TPostData } from "../@types/PostTypes";
|
||||||
import { TUser } from "../@types/UserType";
|
import { TUser } from "../@types/UserType";
|
||||||
|
|
||||||
export const userAtom = atom<TUser>();
|
export const userAtom = atom<TUser>();
|
||||||
@ -7,10 +8,18 @@ export const userAtom = atom<TUser>();
|
|||||||
export const postCreationAtom = atom<string>();
|
export const postCreationAtom = atom<string>();
|
||||||
export const postCreationTitleAtom = atom<string>();
|
export const postCreationTitleAtom = atom<string>();
|
||||||
|
|
||||||
type TPostData = {
|
export const themeAtom = atomWithStorage<"light" | "dark">(
|
||||||
title: string;
|
"theme",
|
||||||
content: string;
|
"light",
|
||||||
};
|
{
|
||||||
|
getItem: (key) => localStorage.getItem(key) as any,
|
||||||
|
setItem: (key, value) => localStorage.setItem(key, value as any),
|
||||||
|
removeItem: (key) => localStorage.removeItem(key),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
getOnInit: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export const storagePostAtom = atomWithStorage<TPostData>(
|
export const storagePostAtom = atomWithStorage<TPostData>(
|
||||||
"draft-post",
|
"draft-post",
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
import Sources from "quill";
|
import { Delta } from "quill/core";
|
||||||
import Quill, { Delta } from "quill/core";
|
import { forwardRef } from "react";
|
||||||
import { forwardRef, useEffect, useRef, useState } from "react";
|
|
||||||
import ReactQuill from "react-quill";
|
|
||||||
|
|
||||||
type TEditor = {
|
type TEditor = {
|
||||||
readOnly?: boolean;
|
readOnly?: boolean;
|
||||||
@ -30,61 +28,55 @@ const modules = {
|
|||||||
* @param onChange - function that accepts Delta element
|
* @param onChange - function that accepts Delta element
|
||||||
*/
|
*/
|
||||||
const Editor = forwardRef((props: TEditor) => {
|
const Editor = forwardRef((props: TEditor) => {
|
||||||
const editor = useRef(null);
|
// const editor = useRef(null);
|
||||||
const [quill, setQuill] = useState<Quill | null>(null);
|
// const [quill, setQuill] = useState<Quill | null>(null);
|
||||||
const [value, setValue] = useState(new Delta());
|
// const [value, setValue] = useState(new Delta());
|
||||||
|
|
||||||
const [loaded, setLoaded] = useState(false);
|
// const [loaded, setLoaded] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
if (editor.current) {
|
// if (editor.current) {
|
||||||
//@ts-ignore
|
// //@ts-ignore
|
||||||
const temp = editor.current.getEditor() as Quill;
|
// const temp = editor.current.getEditor() as Quill;
|
||||||
setQuill(temp);
|
// setQuill(temp);
|
||||||
}
|
// }
|
||||||
return () => {
|
// return () => {
|
||||||
setQuill(null);
|
// setQuill(null);
|
||||||
};
|
// };
|
||||||
}, [editor.current]);
|
// }, [editor.current]);
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
const quill = new Quill(document.createElement("div"));
|
// const quill = new Quill(document.createElement("div"));
|
||||||
const t = quill.clipboard.convert({
|
// console.log(`AMOOOGUS`, props.defaultValue);
|
||||||
html: props.defaultValue as string,
|
|
||||||
}) as Delta;
|
|
||||||
|
|
||||||
if (!loaded) {
|
// const t = quill.clipboard.convert({
|
||||||
setValue(t);
|
// html: props.defaultValue as string,
|
||||||
|
// }) as Delta;
|
||||||
|
|
||||||
console.log(t);
|
// if (!loaded) {
|
||||||
}
|
// setValue(t);
|
||||||
|
// console.log(t);
|
||||||
|
// }
|
||||||
|
|
||||||
setLoaded(true);
|
// setLoaded(true);
|
||||||
}, [props.defaultValue]);
|
// }, [props.defaultValue]);
|
||||||
|
|
||||||
const changeHandler = (
|
// const changeHandler = (
|
||||||
val: string,
|
// val: string,
|
||||||
_changeDelta: Delta,
|
// _changeDelta: Delta,
|
||||||
_source: Sources,
|
// _source: Sources,
|
||||||
_editor: ReactQuill.UnprivilegedEditor
|
// _editor: ReactQuill.UnprivilegedEditor
|
||||||
) => {
|
// ) => {
|
||||||
console.log(val);
|
// console.log(val);
|
||||||
console.log(JSON.stringify(quill?.getContents().ops, null, 2));
|
// console.log(JSON.stringify(quill?.getContents().ops, null, 2));
|
||||||
let fullDelta = quill?.getContents();
|
// let fullDelta = quill?.getContents();
|
||||||
if (props.onChange) props.onChange(val || "");
|
// if (props.onChange) props.onChange(val || "");
|
||||||
if (loaded) setValue(fullDelta || new Delta());
|
// if (loaded) setValue(fullDelta || new Delta());
|
||||||
};
|
// };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="text-editor">
|
<div className="text-editor h-[400px]">
|
||||||
<ReactQuill
|
DEPRECATED
|
||||||
value={value}
|
|
||||||
ref={editor}
|
|
||||||
modules={modules}
|
|
||||||
onChange={changeHandler}
|
|
||||||
theme="snow"
|
|
||||||
placeholder="Type your thoughts here..."
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
85
enshi/src/Components/Editor/TrueEditor.tsx
Normal file
85
enshi/src/Components/Editor/TrueEditor.tsx
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import { Delta, default as Quill, default as Sources } from "quill";
|
||||||
|
import "quill/dist/quill.snow.css"; // make sure to import Quill's CSS
|
||||||
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
|
type TEditor = {
|
||||||
|
readOnly?: boolean;
|
||||||
|
defaultValue?: string | Delta;
|
||||||
|
onChange?: (html: string) => void;
|
||||||
|
onSelectionChange?: (range: any) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const modules = {
|
||||||
|
toolbar: [
|
||||||
|
[{ header: [1, 2, 3, 4, 5, false] }],
|
||||||
|
["bold", "italic", "underline", "strike", "blockquote", "span-wrapper"],
|
||||||
|
[
|
||||||
|
{ list: "ordered" },
|
||||||
|
{ list: "bullet" },
|
||||||
|
{ indent: "-1" },
|
||||||
|
{ indent: "+1" },
|
||||||
|
],
|
||||||
|
["link", "image"],
|
||||||
|
["clean"],
|
||||||
|
[{ align: [] }],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const TrueEditor = (props: TEditor) => {
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
const quillRef = useRef<Quill | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (containerRef.current) {
|
||||||
|
quillRef.current = new Quill(containerRef.current, {
|
||||||
|
modules,
|
||||||
|
theme: "snow",
|
||||||
|
readOnly: props.readOnly || false,
|
||||||
|
placeholder: "Type your thoughts here...",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (props.defaultValue) {
|
||||||
|
if (typeof props.defaultValue === "string") {
|
||||||
|
const delta = quillRef.current.clipboard.convert({ html: props.defaultValue });
|
||||||
|
quillRef.current.setContents(delta, "silent");
|
||||||
|
} else {
|
||||||
|
quillRef.current.setContents(props.defaultValue, "silent");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quillRef.current.on(
|
||||||
|
"text-change",
|
||||||
|
(_delta: Delta, _oldDelta: Delta, _source: Sources) => {
|
||||||
|
if (props.onChange) {
|
||||||
|
const html =
|
||||||
|
containerRef.current?.querySelector(".ql-editor")?.innerHTML ||
|
||||||
|
"";
|
||||||
|
props.onChange(html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (props.onSelectionChange) {
|
||||||
|
quillRef.current.on("selection-change", (range, _oldRange, _source) => {
|
||||||
|
if(props.onSelectionChange) props.onSelectionChange(range);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (quillRef.current) {
|
||||||
|
quillRef.current.off("text-change");
|
||||||
|
quillRef.current.off("selection-change");
|
||||||
|
quillRef.current = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col w-full mx-auto overflow-hidden text-editor flex-grow-1 max-w-pc-width">
|
||||||
|
<div ref={containerRef} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TrueEditor;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { PlusIcon } from "@radix-ui/react-icons";
|
import { Pencil1Icon } from "@radix-ui/react-icons";
|
||||||
import { Button, Text } from "@radix-ui/themes";
|
import { Button, Text } from "@radix-ui/themes";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
@ -8,8 +8,8 @@ export default function CreatePostButton() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Link to={"/create"}>
|
<Link to={"/create"}>
|
||||||
<Button variant="ghost" className="h-full">
|
<Button variant="ghost" className="items-center h-full px-[6px] pr-[8px] py-0 my-auto m-0">
|
||||||
<PlusIcon />
|
<Pencil1Icon />
|
||||||
<Text>{t("createPost")}</Text>
|
<Text>{t("createPost")}</Text>
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
import CreatePostButton from "./CreatePostButton/CreatePostButton";
|
import CreatePostButton from "./CreatePostButton/CreatePostButton";
|
||||||
|
import ThemeChangeButton from "./ThemeChangeButton/ThemeChangeButton";
|
||||||
import UserButton from "./UserButton/UserButton";
|
import UserButton from "./UserButton/UserButton";
|
||||||
|
|
||||||
|
|
||||||
export default function RightButtonBar() {
|
export default function RightButtonBar() {
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-row justify-end flex-1 gap-4'>
|
<div className='flex flex-row items-center justify-end flex-1 gap-2'>
|
||||||
<CreatePostButton />
|
<CreatePostButton />
|
||||||
|
<ThemeChangeButton />
|
||||||
<UserButton />
|
<UserButton />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
import { MoonIcon, SunIcon } from "@radix-ui/react-icons";
|
||||||
|
import { IconButton } from "@radix-ui/themes";
|
||||||
|
import { useAtom } from "jotai";
|
||||||
|
import { themeAtom } from "../../../../AtomStore/AtomStore";
|
||||||
|
|
||||||
|
export default function ThemeChangeButton() {
|
||||||
|
const [theme, setTheme] = useAtom(themeAtom);
|
||||||
|
|
||||||
|
|
||||||
|
const toggleTheme = () => {
|
||||||
|
if(theme === 'light') {
|
||||||
|
setTheme('dark')
|
||||||
|
} else {
|
||||||
|
setTheme('light')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IconButton onClick={toggleTheme} className="mx-0 my-auto rounded-full p-[8px]" variant="ghost">
|
||||||
|
{theme === 'light' ? <SunIcon /> : <MoonIcon />}
|
||||||
|
</IconButton>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import { LaptopIcon, PersonIcon } from "@radix-ui/react-icons";
|
import { LaptopIcon, PersonIcon } from "@radix-ui/react-icons";
|
||||||
import { DropdownMenu, Flex, IconButton, Text } from "@radix-ui/themes";
|
import { DropdownMenu, Flex, IconButton, Text, Tooltip } from "@radix-ui/themes";
|
||||||
import { Icon } from "@radix-ui/themes/dist/esm/components/callout.js";
|
import { Icon } from "@radix-ui/themes/dist/esm/components/callout.js";
|
||||||
import { useAtomValue } from "jotai";
|
import { useAtomValue } from "jotai";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@ -18,9 +18,15 @@ export default function UserButton() {
|
|||||||
<div className="">
|
<div className="">
|
||||||
<DropdownMenu.Root>
|
<DropdownMenu.Root>
|
||||||
<DropdownMenu.Trigger>
|
<DropdownMenu.Trigger>
|
||||||
<IconButton className="cursor-pointer">
|
<Tooltip content={"User menu"} className="w-fit">
|
||||||
<PersonIcon />
|
<IconButton
|
||||||
</IconButton>
|
size={"2"}
|
||||||
|
className="items-center my-auto rounded-full"
|
||||||
|
variant="ghost"
|
||||||
|
>
|
||||||
|
<PersonIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
</DropdownMenu.Trigger>
|
</DropdownMenu.Trigger>
|
||||||
|
|
||||||
<DropdownMenu.Content className="w-fit">
|
<DropdownMenu.Content className="w-fit">
|
||||||
|
|||||||
@ -1,28 +0,0 @@
|
|||||||
import * as RadixTooltip from "@radix-ui/react-tooltip";
|
|
||||||
import { Card, Text, Theme } from "@radix-ui/themes";
|
|
||||||
|
|
||||||
type TTooltipProps = {
|
|
||||||
text: string;
|
|
||||||
} & React.PropsWithChildren;
|
|
||||||
|
|
||||||
export default function Tooltip(props: TTooltipProps) {
|
|
||||||
return (
|
|
||||||
<RadixTooltip.Provider>
|
|
||||||
<RadixTooltip.Root>
|
|
||||||
<RadixTooltip.Trigger>{props.children}</RadixTooltip.Trigger>
|
|
||||||
|
|
||||||
<RadixTooltip.Portal>
|
|
||||||
<RadixTooltip.Content side="top">
|
|
||||||
<RadixTooltip.Content>
|
|
||||||
<Theme panelBackground="translucent">
|
|
||||||
<Card className="p-1 -translate-y-1 w-fit h-fit animate-appearTooltip">
|
|
||||||
<Text>{props.text}</Text>
|
|
||||||
</Card>
|
|
||||||
</Theme>
|
|
||||||
</RadixTooltip.Content>
|
|
||||||
</RadixTooltip.Content>
|
|
||||||
</RadixTooltip.Portal>
|
|
||||||
</RadixTooltip.Root>
|
|
||||||
</RadixTooltip.Provider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,10 +1,10 @@
|
|||||||
import { Box, Container, Flex, ScrollArea } from "@radix-ui/themes";
|
import { Box, Container, Flex } from "@radix-ui/themes";
|
||||||
import { useAtom, useSetAtom } from "jotai";
|
import { useAtom, useSetAtom } from "jotai";
|
||||||
import {
|
import {
|
||||||
postCreationAtom,
|
postCreationAtom,
|
||||||
postCreationTitleAtom,
|
postCreationTitleAtom,
|
||||||
} from "../../AtomStore/AtomStore";
|
} from "../../AtomStore/AtomStore";
|
||||||
import Editor from "../../Components/Editor/Editor";
|
import TrueEditor from "../../Components/Editor/TrueEditor";
|
||||||
import SubmitPostButton from "./SubmitPostButton/SubmitPostButton";
|
import SubmitPostButton from "./SubmitPostButton/SubmitPostButton";
|
||||||
|
|
||||||
export default function PostCreatorPage() {
|
export default function PostCreatorPage() {
|
||||||
@ -14,7 +14,11 @@ export default function PostCreatorPage() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box className="flex flex-col flex-1 overflow-hidden">
|
<Box className="flex flex-col flex-1 overflow-hidden">
|
||||||
<Flex gap={"4"} direction={"column"} className="justify-start overflow-hidden">
|
<Flex
|
||||||
|
gap={"4"}
|
||||||
|
direction={"column"}
|
||||||
|
className="justify-start overflow-hidden"
|
||||||
|
>
|
||||||
<Container>
|
<Container>
|
||||||
<input
|
<input
|
||||||
placeholder={"Post title"}
|
placeholder={"Post title"}
|
||||||
@ -28,11 +32,7 @@ export default function PostCreatorPage() {
|
|||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
<ScrollArea>
|
<TrueEditor onChange={setContentValue} />
|
||||||
<Container>
|
|
||||||
<Editor onChange={setContentValue} />
|
|
||||||
</Container>
|
|
||||||
</ScrollArea>
|
|
||||||
|
|
||||||
<Box className="flex justify-center flex-[1] mb-4">
|
<Box className="flex justify-center flex-[1] mb-4">
|
||||||
<SubmitPostButton className="text-2xl rounded-full w-52" />
|
<SubmitPostButton className="text-2xl rounded-full w-52" />
|
||||||
|
|||||||
@ -2,8 +2,8 @@ import { Box, Container, Flex, Spinner } from "@radix-ui/themes";
|
|||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { axiosLocalhost } from "../../../api/axios/axios";
|
import { axiosLocalhost } from "../../api/axios/axios";
|
||||||
import Editor from "../../../Components/Editor/Editor";
|
import TrueEditor from "../../Components/Editor/TrueEditor";
|
||||||
import SubmitChangesButton from "./SubmitChangesButton/SubmitChangesButton";
|
import SubmitChangesButton from "./SubmitChangesButton/SubmitChangesButton";
|
||||||
|
|
||||||
export default function PostRedactor() {
|
export default function PostRedactor() {
|
||||||
@ -12,7 +12,7 @@ export default function PostRedactor() {
|
|||||||
|
|
||||||
const queryParams = useParams();
|
const queryParams = useParams();
|
||||||
|
|
||||||
const { isPending } = useQuery({
|
const { isLoading } = useQuery({
|
||||||
queryKey: ["changePostKey", queryParams.postId],
|
queryKey: ["changePostKey", queryParams.postId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
try {
|
try {
|
||||||
@ -31,16 +31,20 @@ export default function PostRedactor() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
gcTime: 0,
|
gcTime: 0,
|
||||||
refetchOnMount: true
|
refetchOnMount: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box className="flex flex-col flex-1">
|
<Box className="flex flex-col flex-1 overflow-hidden">
|
||||||
<Flex gap={"4"} direction={"column"} className="flex-[1]">
|
<Flex
|
||||||
<Container className="flex-[1]">
|
gap={"4"}
|
||||||
|
direction={"column"}
|
||||||
|
className="overflow-hidden"
|
||||||
|
>
|
||||||
|
<Container className="">
|
||||||
<input
|
<input
|
||||||
disabled={isPending}
|
disabled={isLoading}
|
||||||
placeholder={"Post title"}
|
placeholder={"Post title"}
|
||||||
className="mb-2 border-0 border-b-[1px]
|
className="mb-2 border-0 border-b-[1px]
|
||||||
outline-none w-full border-b-gray-400
|
outline-none w-full border-b-gray-400
|
||||||
@ -52,22 +56,32 @@ export default function PostRedactor() {
|
|||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
<Container className="overflow-y-auto flex-grow-[100]">
|
{/* <Container className="overflow-hidden flex-grow-[100]">
|
||||||
{isPending ? (
|
{isPending ? (
|
||||||
<Spinner />
|
<Spinner />
|
||||||
) : (
|
) : (
|
||||||
<Editor
|
<Editor
|
||||||
defaultValue={contentValue}
|
defaultValue={contentValue}
|
||||||
onChange={setContentValue}
|
onChange={setContentValue}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Container>
|
</Container> */}
|
||||||
|
|
||||||
<Box className="flex justify-center flex-[1] mb-4">
|
{isLoading ? (
|
||||||
|
<Spinner />
|
||||||
|
) : (
|
||||||
|
<TrueEditor
|
||||||
|
defaultValue={contentValue}
|
||||||
|
onChange={setContentValue}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Box className="flex justify-center flex-[1] mb-4 ">
|
||||||
<SubmitChangesButton
|
<SubmitChangesButton
|
||||||
contentValue={contentValue}
|
contentValue={contentValue}
|
||||||
titleValue={titleValue}
|
titleValue={titleValue}
|
||||||
className="text-2xl rounded-full w-52" />
|
className="text-2xl rounded-full w-52"
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Box>
|
</Box>
|
||||||
@ -3,8 +3,8 @@ import { useMutation } from "@tanstack/react-query";
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import { axiosLocalhost } from "../../../../api/axios/axios";
|
import { axiosLocalhost } from "../../../api/axios/axios";
|
||||||
import useToast from "../../../../hooks/useToast";
|
import useToast from "../../../hooks/useToast";
|
||||||
|
|
||||||
type TSubmitChangesButton = {
|
type TSubmitChangesButton = {
|
||||||
className: string;
|
className: string;
|
||||||
@ -11,9 +11,9 @@ import ProfilePage from "../layout/ProfilePage/ProfilePage";
|
|||||||
import AuthPageWrapper from "../Pages/AuthPageWrapper/AuthPageWrapper";
|
import AuthPageWrapper from "../Pages/AuthPageWrapper/AuthPageWrapper";
|
||||||
import BlogPage from "../Pages/BlogPage/BlogPage";
|
import BlogPage from "../Pages/BlogPage/BlogPage";
|
||||||
import LoginPage from "../Pages/LoginRegisterPage/LoginPage/LoginPage";
|
import LoginPage from "../Pages/LoginRegisterPage/LoginPage/LoginPage";
|
||||||
import PostRedactor from "../Pages/LoginRegisterPage/PostRedactor/PostRedactor";
|
|
||||||
import RegisterPage from "../Pages/LoginRegisterPage/RegisterPage/RegisterPage";
|
import RegisterPage from "../Pages/LoginRegisterPage/RegisterPage/RegisterPage";
|
||||||
import PostCreatorPage from "../Pages/PostCreatorPage/PostCreatorPage";
|
import PostCreatorPage from "../Pages/PostCreatorPage/PostCreatorPage";
|
||||||
|
import PostRedactor from "../Pages/PostRedactor/PostRedactor";
|
||||||
import RandomPostsPage from "../Pages/RandomPostsPage/RandomPostsPage";
|
import RandomPostsPage from "../Pages/RandomPostsPage/RandomPostsPage";
|
||||||
import UserBlogsPage from "../Pages/UserBlogsPage/UserBlogsPage";
|
import UserBlogsPage from "../Pages/UserBlogsPage/UserBlogsPage";
|
||||||
import UserPostsPage from "../Pages/UserPostsPage/UserPostsPage";
|
import UserPostsPage from "../Pages/UserPostsPage/UserPostsPage";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user