From f5dff1e6550d69786f30c342c1681eb2f0f9e765 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Thu, 25 Dec 2025 19:02:52 +0700 Subject: [PATCH] feat: svg change --- .../launches/helpers/date.picker.tsx | 17 +- .../launches/helpers/top.title.component.tsx | 29 +- .../components/launches/repeat.component.tsx | 38 +- .../components/launches/select.customer.tsx | 31 +- .../components/launches/tags.component.tsx | 66 +- .../src/components/launches/up.down.arrow.tsx | 19 +- .../src/components/media/media.component.tsx | 254 +---- .../src/components/new-launch/editor.tsx | 128 +-- .../components/new-launch/manage.modal.tsx | 558 +---------- .../components/new-launch/select.current.tsx | 17 +- .../src/components/ui/icons/index.tsx | 878 ++++++++++++++++++ apps/frontend/tailwind.config.js | 1 + 12 files changed, 954 insertions(+), 1082 deletions(-) create mode 100644 apps/frontend/src/components/ui/icons/index.tsx diff --git a/apps/frontend/src/components/launches/helpers/date.picker.tsx b/apps/frontend/src/components/launches/helpers/date.picker.tsx index 2abebc7d..585f8e91 100644 --- a/apps/frontend/src/components/launches/helpers/date.picker.tsx +++ b/apps/frontend/src/components/launches/helpers/date.picker.tsx @@ -6,6 +6,7 @@ import { Button } from '@gitroom/react/form/button'; import { isUSCitizen } from './isuscitizen.utils'; import { useT } from '@gitroom/react/translation/get.transation.service.client'; import { newDayjs } from '@gitroom/frontend/components/layout/set.timezone'; +import { CalendarIcon } from '@gitroom/frontend/components/ui/icons'; export const DatePicker: FC<{ date: dayjs.Dayjs; onChange: (day: dayjs.Dayjs) => void; @@ -39,21 +40,7 @@ export const DatePicker: FC<{ ref={ref} >
- - - +
{date.format(isUSCitizen() ? 'MM/DD/YYYY hh:mm A' : 'DD/MM/YYYY HH:mm')} diff --git a/apps/frontend/src/components/launches/helpers/top.title.component.tsx b/apps/frontend/src/components/launches/helpers/top.title.component.tsx index 2a44f958..48624e60 100644 --- a/apps/frontend/src/components/launches/helpers/top.title.component.tsx +++ b/apps/frontend/src/components/launches/helpers/top.title.component.tsx @@ -1,6 +1,7 @@ import { FC, ReactNode } from 'react'; import { useT } from '@gitroom/react/translation/get.transation.service.client'; import clsx from 'clsx'; +import { ExpandIcon, CollapseIcon } from '@gitroom/frontend/components/ui/icons'; export const TopTitle: FC<{ title: string; @@ -44,33 +45,9 @@ export const TopTitle: FC<{ {shouldExpend !== undefined && (
{!shouldExpend ? ( - - - + ) : ( - - - + )}
)} diff --git a/apps/frontend/src/components/launches/repeat.component.tsx b/apps/frontend/src/components/launches/repeat.component.tsx index 416426ab..9bc6e140 100644 --- a/apps/frontend/src/components/launches/repeat.component.tsx +++ b/apps/frontend/src/components/launches/repeat.component.tsx @@ -4,6 +4,7 @@ import { useT } from '@gitroom/react/translation/get.transation.service.client'; import { useClickOutside } from '@mantine/hooks'; import { isUSCitizen } from '@gitroom/frontend/components/launches/helpers/isuscitizen.utils'; import clsx from 'clsx'; +import { RepeatIcon, DropdownArrowIcon } from '@gitroom/frontend/components/ui/icons'; const list = [ { value: 1, @@ -81,28 +82,7 @@ export const RepeatComponent: FC<{ className="px-[16px] justify-center flex gap-[8px] items-center h-full select-none flex-1" >
- - - - - - - - - - +
{repeat @@ -110,19 +90,7 @@ export const RepeatComponent: FC<{ : t('repeat_post_every', 'Repeat Post Every...')}
- - - +
{isOpen && ( diff --git a/apps/frontend/src/components/launches/select.customer.tsx b/apps/frontend/src/components/launches/select.customer.tsx index 157e5365..f1ed526f 100644 --- a/apps/frontend/src/components/launches/select.customer.tsx +++ b/apps/frontend/src/components/launches/select.customer.tsx @@ -7,6 +7,7 @@ import { useClickOutside } from '@mantine/hooks'; import { useToaster } from '@gitroom/react/toaster/toaster'; import { useLaunchStore } from '@gitroom/frontend/components/new-launch/store'; import { useShallow } from 'zustand/react/shallow'; +import { UserIcon, DropdownArrowIcon } from '@gitroom/frontend/components/ui/icons'; export const SelectCustomer: FC<{ onChange: (value: string) => void; @@ -60,36 +61,10 @@ export const SelectCustomer: FC<{ )} >
- - - +
- - - +
{open && ( diff --git a/apps/frontend/src/components/launches/tags.component.tsx b/apps/frontend/src/components/launches/tags.component.tsx index 457233b5..0679c4ea 100644 --- a/apps/frontend/src/components/launches/tags.component.tsx +++ b/apps/frontend/src/components/launches/tags.component.tsx @@ -11,6 +11,7 @@ import { useT } from '@gitroom/react/translation/get.transation.service.client'; import { useClickOutside } from '@mantine/hooks'; import clsx from 'clsx'; import { useModals } from '@gitroom/frontend/components/layout/new-modal'; +import { TagIcon, DropdownArrowIcon, PlusIcon, CheckmarkIcon } from '@gitroom/frontend/components/ui/icons'; export const TagsComponent: FC<{ name: string; @@ -109,21 +110,7 @@ export const TagsComponentInner: FC<{ className="px-[16px] justify-center flex gap-[8px] items-center h-full select-none flex-1" >
- - - +
{tagValue.length === 0 ? ( @@ -143,19 +130,7 @@ export const TagsComponentInner: FC<{ )}
- - - +
{isOpen && ( @@ -203,21 +178,7 @@ export const TagsComponentInner: FC<{ className="cursor-pointer gap-[8px] flex w-full h-[34px] rounded-[8px] mt-[12px] px-[16px] justify-center items-center bg-[#612BD3] text-white" >
- - - +
Add New Tag
@@ -239,24 +200,7 @@ const Check: FC<{ value: boolean; onChange: (value: boolean) => void }> = ({ value && 'bg-[#612BD3]' )} > - {value ? ( - - - - ) : ( - '' - )} + {value ? : ''} ); }; diff --git a/apps/frontend/src/components/launches/up.down.arrow.tsx b/apps/frontend/src/components/launches/up.down.arrow.tsx index f88b29fd..04a756c6 100644 --- a/apps/frontend/src/components/launches/up.down.arrow.tsx +++ b/apps/frontend/src/components/launches/up.down.arrow.tsx @@ -1,28 +1,17 @@ import { FC, useCallback } from 'react'; import clsx from 'clsx'; +import { ChevronUpIcon } from '@gitroom/frontend/components/ui/icons'; + const Arrow: FC<{ flip: boolean; }> = (props) => { const { flip } = props; return ( - - - + /> ); }; export const UpDownArrow: FC<{ diff --git a/apps/frontend/src/components/media/media.component.tsx b/apps/frontend/src/components/media/media.component.tsx index 010208a8..8c810dbc 100644 --- a/apps/frontend/src/components/media/media.component.tsx +++ b/apps/frontend/src/components/media/media.component.tsx @@ -18,17 +18,14 @@ import { Media } from '@prisma/client'; import { useMediaDirectory } from '@gitroom/react/helpers/use.media.directory'; import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values'; import EventEmitter from 'events'; -import { TopTitle } from '@gitroom/frontend/components/launches/helpers/top.title.component'; import clsx from 'clsx'; import { VideoFrame } from '@gitroom/react/helpers/video.frame'; import { - MultipartFileUploader, useUppyUploader, } from '@gitroom/frontend/components/media/new.uploader'; import dynamic from 'next/dynamic'; import { useUser } from '@gitroom/frontend/components/layout/user.context'; import { AiImage } from '@gitroom/frontend/components/launches/ai.image'; -import Image from 'next/image'; import { DropFiles } from '@gitroom/frontend/components/layout/drop.files'; import { deleteDialog } from '@gitroom/react/helpers/delete.dialog'; import { useT } from '@gitroom/react/translation/get.transation.service.client'; @@ -36,13 +33,23 @@ import { ThirdPartyMedia } from '@gitroom/frontend/components/third-parties/thir import { ReactSortable } from 'react-sortablejs'; import { MediaComponentInner, - useMediaSettings, } from '@gitroom/frontend/components/launches/helpers/media.settings.component'; -import { useLaunchStore } from '@gitroom/frontend/components/new-launch/store'; import { AiVideo } from '@gitroom/frontend/components/launches/ai.video'; import { useModals } from '@gitroom/frontend/components/layout/new-modal'; import { Dashboard } from '@uppy/react'; -import { timer } from '@gitroom/helpers/utils/timer'; +import { + ChevronLeftIcon, + ChevronRightIcon, + PlusIcon, + DeleteCircleIcon, + CloseCircleIcon, + DragHandleIcon, + MediaSettingsIcon, + InsertMediaIcon, + DesignMediaIcon, + VerticalDividerIcon, + NoMediaIcon, +} from '@gitroom/frontend/components/ui/icons'; const Polonto = dynamic( () => import('@gitroom/frontend/components/launches/polonto') ); @@ -71,20 +78,7 @@ export const Pagination: FC<{ aria-label="Go to previous page" onClick={() => setPage(current - 1)} > - - - + {t('previous', 'Previous')} @@ -115,20 +109,7 @@ export const Pagination: FC<{ onClick={() => setPage(current + 1)} > {t('next', 'Next')} - - - + @@ -288,21 +269,7 @@ export const MediaBox: FC<{ onClick={() => uploaderRef?.current?.click()} className="cursor-pointer bg-btnSimple changeColor flex gap-[8px] h-[44px] px-[18px] justify-center items-center rounded-[8px]" > - - - +
Upload
); @@ -366,63 +333,7 @@ export const MediaBox: FC<{ > {!isLoading && !data?.results?.length && ( <> - - - - - - - - - - +
You don't have any media yet
@@ -478,27 +389,10 @@ export const MediaBox: FC<{ {selected.findIndex((z: any) => z.id === media.id) + 1} ) : ( - - - - + /> )}
{media.path.indexOf('mp4') > -1 ? ( @@ -690,26 +584,7 @@ export const MultiMediaComponent: FC<{ {currentMedia.map((media, index) => (
- - - - +
- - - +
{media?.path?.indexOf('mp4') > -1 ? ( @@ -766,20 +629,10 @@ export const MultiMediaComponent: FC<{ )}
- - - + />
))} @@ -795,28 +648,7 @@ export const MultiMediaComponent: FC<{ >
- - - - - - - - - - +
{t('insert_media', 'Insert Media')} @@ -829,28 +661,7 @@ export const MultiMediaComponent: FC<{ >
- - - - - - - - - - +
{t('design_media', 'Design Media')} @@ -868,20 +679,7 @@ export const MultiMediaComponent: FC<{ )}
- - - +
{!!toolBar && (
diff --git a/apps/frontend/src/components/new-launch/editor.tsx b/apps/frontend/src/components/new-launch/editor.tsx index eb9e51a0..a28284f6 100644 --- a/apps/frontend/src/components/new-launch/editor.tsx +++ b/apps/frontend/src/components/new-launch/editor.tsx @@ -60,6 +60,13 @@ import { useFetch } from '@gitroom/helpers/utils/custom.fetch'; import { AComponent } from '@gitroom/frontend/components/new-launch/a.component'; import { Placeholder } from '@tiptap/extensions'; import { InformationComponent } from '@gitroom/frontend/components/launches/information.component'; +import { + LockIcon, + ConnectionLineIcon, + ResetIcon, + TrashIcon, + EmojiIcon, +} from '@gitroom/frontend/components/ui/icons'; const InterceptBoldShortcut = Extension.create({ name: 'preventBoldWithUnderline', @@ -345,21 +352,7 @@ export const EditorWrapper: FC<{
- - - +
@@ -381,21 +374,7 @@ export const EditorWrapper: FC<{ >
- - - +
@@ -427,20 +406,7 @@ export const EditorWrapper: FC<{
{index > 0 && (
- - - +
)}
- - - +
Back to global @@ -520,25 +472,12 @@ export const EditorWrapper: FC<{ onChange={changeOrder(index)} /> {items.length > 1 && ( - - - + className="cursor-pointer text-[#FF3F3F]" + /> )}
@@ -783,44 +722,7 @@ export const Editor: FC<{ className="select-none cursor-pointer rounded-[6px] w-[30px] h-[30px] bg-newColColor flex justify-center items-center" onClick={() => setEmojiPickerOpen(!emojiPickerOpen)} > - - - - - - +
= (props) => { )} >
- - - - +
{currentIntegrationText} Settings
- - - +
= (props) => {
Post Preview
- - - +
@@ -489,21 +440,7 @@ export const ManageModal: FC = (props) => { {existingData?.integration && ( @@ -552,19 +489,7 @@ export const ManageModal: FC = (props) => { : t('update', 'Update')}
- - - +
@@ -606,462 +531,3 @@ After using the addPostFor{num} it will create a new addPostContentFor{num+ 1} f
); }; -export const ManageModalA: FC = (props) => { - const t = useT(); - const fetch = useFetch(); - const ref = useRef(null); - const existingData = useExistingData(); - const [loading, setLoading] = useState(false); - const toaster = useToaster(); - const modal = useModals(); - - const { addEditSets, mutate, customClose, dummy } = props; - - const { - selectedIntegrations, - hide, - date, - setDate, - repeater, - setRepeater, - tags, - setTags, - integrations, - setSelectedIntegrations, - locked, - activateExitButton, - } = useLaunchStore( - useShallow((state) => ({ - hide: state.hide, - date: state.date, - setDate: state.setDate, - repeater: state.repeater, - setRepeater: state.setRepeater, - tags: state.tags, - setTags: state.setTags, - selectedIntegrations: state.selectedIntegrations, - integrations: state.integrations, - setSelectedIntegrations: state.setSelectedIntegrations, - locked: state.locked, - activateExitButton: state.activateExitButton, - })) - ); - - const deletePost = useCallback(async () => { - setLoading(true); - if ( - !(await deleteDialog( - 'Are you sure you want to delete this post?', - 'Yes, delete it!' - )) - ) { - setLoading(false); - return; - } - await fetch(`/posts/${existingData.group}`, { - method: 'DELETE', - }); - mutate(); - modal.closeAll(); - return; - }, [existingData, mutate, modal]); - - const askClose = useCallback(async () => { - if (!activateExitButton || dummy) { - return; - } - - if ( - await deleteDialog( - t( - 'are_you_sure_you_want_to_close_this_modal_all_data_will_be_lost', - 'Are you sure you want to close this modal? (all data will be lost)' - ), - t('yes_close_it', 'Yes, close it!') - ) - ) { - if (customClose) { - customClose(); - return; - } - modal.closeAll(); - } - }, [activateExitButton, dummy]); - - const changeCustomer = useCallback( - (customer: string) => { - const neededIntegrations = integrations.filter( - (p) => p?.customer?.id === customer - ); - setSelectedIntegrations( - neededIntegrations.map((p) => ({ - settings: {}, - selectedIntegrations: p, - })) - ); - }, - [integrations] - ); - - const schedule = useCallback( - (type: 'draft' | 'now' | 'schedule') => async () => { - setLoading(true); - const checkAllValid = await ref.current.checkAllValid(); - if (type !== 'draft') { - const notEnoughChars = checkAllValid.filter((p: any) => { - return p.values.some((a: any) => { - return ( - countCharacters( - stripHtmlValidation('normal', a.content, true), - p?.integration?.identifier || '' - ) === 0 && a.media?.length === 0 - ); - }); - }); - - for (const item of notEnoughChars) { - toaster.show( - '' + - item.integration.name + - ' Your post should have at least one character or one image.', - 'warning' - ); - setLoading(false); - item.preview(); - return; - } - - for (const item of checkAllValid) { - if (item.valid === false) { - toaster.show('Some fields are not valid', 'warning'); - item.fix(); - setLoading(false); - return; - } - - if (item.errors !== true) { - toaster.show( - `${capitalize(item.integration.identifier.split('-')[0])} (${ - item.integration.name - }): ${item.errors}`, - 'warning' - ); - item.preview(); - setLoading(false); - return; - } - } - - const sliceNeeded = checkAllValid.filter((p: any) => { - return p.values.some((a: any) => { - const strip = stripHtmlValidation('normal', a.content, true); - const weightedLength = countCharacters( - strip, - p?.integration?.identifier || '' - ); - const totalCharacters = - weightedLength > strip.length ? weightedLength : strip.length; - - return totalCharacters > (p.maximumCharacters || 1000000); - }); - }); - - for (const item of sliceNeeded) { - toaster.show( - `${item?.integration?.name} (${item?.integration?.identifier}) post is too long, please fix it`, - 'warning' - ); - item.preview(); - setLoading(false); - return; - } - } - - const shortLinkUrl = dummy - ? { ask: false } - : await ( - await fetch('/posts/should-shortlink', { - method: 'POST', - body: JSON.stringify({ - messages: checkAllValid.flatMap((p: any) => - p.values.flatMap((a: any) => a.content) - ), - }), - }) - ).json(); - - const shortLink = !shortLinkUrl.ask - ? false - : await deleteDialog( - 'Do you want to shortlink the URLs? it will let you get statistics over clicks', - 'Yes, shortlink it!' - ); - - const group = existingData.group || makeId(10); - const data = { - type, - ...(repeater ? { inter: repeater } : {}), - tags, - shortLink, - date: date.utc().format('YYYY-MM-DDTHH:mm:ss'), - posts: checkAllValid.map((post: any) => ({ - integration: { - id: post.integration.id, - }, - group, - settings: { ...(post.settings || {}) }, - value: post.values.map((value: any) => ({ - ...(value.id ? { id: value.id } : {}), - content: value.content, - image: - (value?.media || []).map( - ({ id, path, alt, thumbnail, thumbnailTimestamp }: any) => ({ - id, - path, - alt, - thumbnail, - thumbnailTimestamp, - }) - ) || [], - })), - })), - }; - - if (dummy) { - modal.openModal({ - title: '', - children: , - classNames: { - modal: 'w-[100%] bg-transparent text-textColor', - }, - size: '100%', - withCloseButton: false, - closeOnEscape: true, - closeOnClickOutside: true, - }); - - setLoading(false); - } - - if (!dummy) { - addEditSets - ? addEditSets(data) - : await fetch('/posts', { - method: 'POST', - body: JSON.stringify(data), - }); - - if (!addEditSets) { - mutate(); - toaster.show( - !existingData.integration - ? 'Added successfully' - : 'Updated successfully' - ); - } - if (customClose) { - setTimeout(() => { - customClose(); - }, 2000); - } - - if (!addEditSets) { - modal.closeAll(); - } - } - }, - [ref, repeater, tags, date, addEditSets, dummy] - ); - - return ( - <> -
-
-
- -
- {!dummy && ( - - )} - -
-
- - -
- {!existingData.integration && } -
-
- {!hide && } -
-
-
-
-
-
-
-
- {!!existingData.integration && ( - - )} - - {!addEditSets && !dummy && ( - - )} - - {addEditSets && ( - - )} - {!addEditSets && ( - - )} -
-
-
-
-
-
-
- -
-
- {!dummy && ( - setTags(e.target.value)} - /> - )} -
- {!dummy && ( - - )} -
- - - -
-
-
- -
-
-
- - ); -}; diff --git a/apps/frontend/src/components/new-launch/select.current.tsx b/apps/frontend/src/components/new-launch/select.current.tsx index 53350bbe..4f0d9c49 100644 --- a/apps/frontend/src/components/new-launch/select.current.tsx +++ b/apps/frontend/src/components/new-launch/select.current.tsx @@ -5,6 +5,7 @@ import { useLaunchStore } from '@gitroom/frontend/components/new-launch/store'; import clsx from 'clsx'; import Image from 'next/image'; import { useShallow } from 'zustand/react/shallow'; +import { GlobalIcon } from '@gitroom/frontend/components/ui/icons'; export function useHasScroll(ref: RefObject): boolean { const [hasHorizontalScroll, setHasHorizontalScroll] = useState(false); @@ -87,21 +88,7 @@ export const SelectCurrent: FC = () => { )} >
- - - +
{selectedIntegrations.map(({ integration }) => ( diff --git a/apps/frontend/src/components/ui/icons/index.tsx b/apps/frontend/src/components/ui/icons/index.tsx new file mode 100644 index 00000000..78758ad4 --- /dev/null +++ b/apps/frontend/src/components/ui/icons/index.tsx @@ -0,0 +1,878 @@ +import React, { FC, SVGProps, useEffect } from 'react'; +import clsx from 'clsx'; +import useCookie from 'react-use-cookie'; +import { modeEmitter } from '@gitroom/frontend/components/layout/mode.component'; + +export type IconProps = SVGProps & { + size?: number; +}; + +// Settings/Gear Icon +export const SettingsIcon: FC = ({ + size = 20, + className, + ...props +}) => ( + + + + +); + +// Chevron Down Icon (rotatable) +export const ChevronDownIcon: FC = ({ + size = 20, + className, + rotated, + ...props +}) => ( + + + +); + +// Chevron Up Icon +export const ChevronUpIcon: FC = ({ + size = 20, + className, + ...props +}) => ( + + + +); + +// Close/X Icon +export const CloseIcon: FC = ({ + size = 20, + className, + ...props +}) => ( + + + +); + +// Small Close Icon (10x11 variant) +export const CloseIconSmall: FC = ({ + size = 10, + className, + ...props +}) => ( + + + +); + +// Trash/Delete Icon +export const TrashIcon: FC = ({ + size = 20, + className, + ...props +}) => ( + + + +); + +// Dropdown Arrow (filled triangle) +export const DropdownArrowIcon: FC = ({ + size = 20, + className, + rotated, + ...props +}) => ( + + + +); + +// Small Dropdown Arrow (6x4) +export const DropdownArrowSmallIcon: FC = ({ + className, + rotated, + ...props +}) => ( + + + +); + +// Calendar Icon +export const CalendarIcon: FC = ({ className, ...props }) => ( + + + +); + +// Repeat/Cycle Icon +export const RepeatIcon: FC = ({ + size = 20, + className, + ...props +}) => ( + + + + + + + + + + +); + +// Tag Icon +export const TagIcon: FC = ({ className, ...props }) => ( + + + +); + +// Plus Icon +export const PlusIcon: FC = ({ size = 16, className, ...props }) => ( + + + +); + +// Checkmark Icon +export const CheckmarkIcon: FC = ({ className, ...props }) => ( + + + +); + +// Global/Planet Icon +export const GlobalIcon: FC = ({ + size = 20, + className, + ...props +}) => ( + + + +); + +// User Icon +export const UserIcon: FC = ({ size = 20, className, ...props }) => ( + + + +); + +// Expand Icon +export const ExpandIcon: FC = ({ + size = 24, + className, + ...props +}) => ( + + + +); + +// Collapse Icon +export const CollapseIcon: FC = ({ + size = 24, + className, + ...props +}) => ( + + + +); + +// Lock Icon +export const LockIcon: FC = ({ size = 32, className, ...props }) => ( + + + +); + +// Connection Line Icon (for thread/comment indication) +export const ConnectionLineIcon: FC = ({ className, ...props }) => ( + + + +); + +// Reset/Back to Global Icon +export const ResetIcon: FC = ({ + size = 16, + className, + ...props +}) => ( + + + +); + +// Emoji Icon +export const EmojiIcon: FC = ({ + size = 16, + className, + ...props +}) => ( + + + + + + +); + +// Chevron Left Icon +export const ChevronLeftIcon: FC = ({ + size = 24, + className, + ...props +}) => ( + + + +); + +// Chevron Right Icon +export const ChevronRightIcon: FC = ({ + size = 24, + className, + ...props +}) => ( + + + +); + +// Delete Circle Icon (for media delete) +export const DeleteCircleIcon: FC = ({ + size = 18, + className, + ...props +}) => ( + + + + +); + +// Close Circle Icon (smaller, for clearing media) +export const CloseCircleIcon: FC = ({ + size = 15, + className, + ...props +}) => ( + + + +); + +// Drag Handle Icon +export const DragHandleIcon: FC = ({ + size = 15, + className, + ...props +}) => ( + + + + +); + +// Media Settings Icon (gear for media) +export const MediaSettingsIcon: FC = ({ + size = 40, + className, + ...props +}) => ( + + + +); + +// Insert Media Icon +export const InsertMediaIcon: FC = ({ + size = 16, + className, + ...props +}) => ( + + + + + + + + + + +); + +// Design Media Icon (pencil/edit) +export const DesignMediaIcon: FC = ({ + size = 16, + className, + ...props +}) => ( + + + + + + + + + + +); + +// Vertical Divider Icon +export const VerticalDividerIcon: FC = ({ className, ...props }) => ( + + + +); + +export const NoMediaIcon: FC = () => { + const [mode, setMode] = useCookie('mode', 'dark'); + + useEffect(() => { + modeEmitter.on('mode', (value) => { + setMode(value); + }); + + return () => { + modeEmitter.removeAllListeners(); + }; + }, []); + + return ( + <> + {mode === 'light' ? ( + + + + + + + + + + + ) : ( + + + + + + + + + + + )} + + ); +}; diff --git a/apps/frontend/tailwind.config.js b/apps/frontend/tailwind.config.js index 15e6a72b..0fd050db 100644 --- a/apps/frontend/tailwind.config.js +++ b/apps/frontend/tailwind.config.js @@ -1,5 +1,6 @@ const { join } = require('path'); module.exports = { + darkMode: 'class', content: ['./src/**/*.{ts,tsx,html}', '../../libraries/**/*.{ts,tsx,html}'], theme: { extend: {