diff --git a/src/components/Layout/SettingsContentLayout/SettingsContentLayout.tsx b/src/components/Layout/SettingsContentLayout/SettingsContentLayout.tsx index fb6b1c31..cd2b596f 100644 --- a/src/components/Layout/SettingsContentLayout/SettingsContentLayout.tsx +++ b/src/components/Layout/SettingsContentLayout/SettingsContentLayout.tsx @@ -4,18 +4,24 @@ type SettingsContentLayoutProps = { title: string description: string children: React.ReactNode + actions?: React.ReactNode } export const SettingsContentLayout = ({ title, description, + actions, children, }: SettingsContentLayoutProps) => { return (
-

{title}

-

{description}

+
+

{title}

+

{description}

+
+ + {actions &&
{actions}
}
{children}
diff --git a/src/components/Layout/SettingsContentLayout/settingsContentLayout.css b/src/components/Layout/SettingsContentLayout/settingsContentLayout.css index 07437110..a79379a8 100644 --- a/src/components/Layout/SettingsContentLayout/settingsContentLayout.css +++ b/src/components/Layout/SettingsContentLayout/settingsContentLayout.css @@ -15,23 +15,33 @@ gap: 16px; } .settingsContent header { + display: flex; + justify-content: space-between; + align-items: center; +} + +.settingsContent .settingsHeader { display: flex; flex-direction: column; row-gap: 8px; } -.settingsContent header .title { +.settingsContent .settingsHeader .title { font-size: 24px; margin: 0; padding: 0; color: var(--primary-text-color); } -.settingsContent header .description { +.settingsContent .settingsHeader .description { font-size: 14px; margin: 0; padding: 0; color: var(--secondary-text-color); } - +.settingsContent .actions { + display: flex; + justify-content: space-between; + align-items: center; +} @media only screen and (max-width: 768px) { .settingsContent { padding: 16px; diff --git a/src/features/settings/components/BookmarkSettings/BookmarkSettings.tsx b/src/features/settings/components/BookmarkSettings/BookmarkSettings.tsx index 86ca31d3..3683e9ed 100644 --- a/src/features/settings/components/BookmarkSettings/BookmarkSettings.tsx +++ b/src/features/settings/components/BookmarkSettings/BookmarkSettings.tsx @@ -1,4 +1,6 @@ +import { useRef } from 'react' import { BiBookmarkMinus } from 'react-icons/bi' +import { RiFileDownloadFill, RiFileUploadFill } from 'react-icons/ri' import toast from 'react-simple-toasts' import { CardLink } from 'src/components/Elements' import { SettingsContentLayout } from 'src/components/Layout/SettingsContentLayout' @@ -60,17 +62,82 @@ const BookmarkItem = ({ item, appendRef = false }: BookmarkItemProps) => { } export const BookmarkSettings = () => { - const { userBookmarks } = useBookmarks() + const inputFile = useRef(null) + const { initState, userBookmarks } = useBookmarks() + + const importBookmarks = () => { + inputFile.current?.click() + } + + const exportBookmarks = () => { + const blob = new Blob([JSON.stringify(userBookmarks, null, 2)], { + type: 'application/json', + }) + const downloadURL = URL.createObjectURL(blob) + const link = document.createElement('a') + link.href = downloadURL + link.download = 'hackertabBookmarks' + link.click() + } + + const handleFileChange = (event: any) => { + const file = event.target.files?.[0] + if (file) { + const reader = new FileReader() + reader.onload = () => { + const importData: BookmarkedPost[] = JSON.parse(reader.result as string) + const validatedData = importData + .filter( + (data: BookmarkedPost) => + data.title && + data.url && + !userBookmarks.some((bm) => bm.title === data.title && bm.url === data.url) + ) + .map((data) => ({ + title: data.title, + url: data.url, + source: data.source || '', + sourceType: data.sourceType || '', + })) + initState({ + userBookmarks: [...userBookmarks, ...validatedData], + }) + toast('Your bookmarks have been successfully imported', { theme: 'defaultToast' }) + } + reader.readAsText(file) + } + } return ( - -
- {userBookmarks.map((bm) => ( - - ))} -
-
+ <> + + + + + + }> +
+ {userBookmarks.map((bm) => ( + + ))} +
+
+ ) } diff --git a/src/features/settings/components/BookmarkSettings/bookmarkSettings.css b/src/features/settings/components/BookmarkSettings/bookmarkSettings.css index 6775a57c..889f7920 100644 --- a/src/features/settings/components/BookmarkSettings/bookmarkSettings.css +++ b/src/features/settings/components/BookmarkSettings/bookmarkSettings.css @@ -53,3 +53,31 @@ align-items: center; justify-content: center; } + +/* Export/Import Bookmark Buttons */ + +/* removing that ugly default button design */ +.notbtn { + background: none; + color: inherit; + border: none; + padding: 0; + font: inherit; + cursor: pointer; + outline: inherit; +} + +.btn-group { + padding: 10px; + display: flex; +} + +.btn { + border-radius: 12px; + padding: 6px 12px; + margin-right: 5px; + background-color: var(--chip-background); +} +.btn:hover { + filter: brightness(85%); +} diff --git a/src/features/settings/components/SearchEngineSettings.tsx b/src/features/settings/components/SearchEngineSettings.tsx index ebf2d6ee..f3cc2154 100644 --- a/src/features/settings/components/SearchEngineSettings.tsx +++ b/src/features/settings/components/SearchEngineSettings.tsx @@ -49,10 +49,12 @@ export const SearchEngineSettings = () => {
<>
-

Add new Search Engine

-

- Can't find your favorite search engine? Add it here and it. -

+
+

Add new Search Engine

+

+ Can't find your favorite search engine? Add it here and it. +

+
diff --git a/src/features/settings/components/SourceSettings.tsx b/src/features/settings/components/SourceSettings.tsx index a1099179..b9da4deb 100644 --- a/src/features/settings/components/SourceSettings.tsx +++ b/src/features/settings/components/SourceSettings.tsx @@ -69,11 +69,13 @@ export const SourceSettings = () => {
<>
-

Add new Source

-

- Can't find your favorite source? Add its RSS feed URL here and it will be available in - your feed. -

+
+

Add new Source

+

+ Can't find your favorite source? Add its RSS feed URL here and it will be available + in your feed. +

+