mirror of
https://github.com/Sonny93/my-links.git
synced 2025-12-09 15:05:35 +00:00
feat: create basic settings modal
This commit is contained in:
@@ -9,7 +9,7 @@ const ModalWrapper = styled.div(({ theme }) => ({
|
|||||||
height: '100%',
|
height: '100%',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
background: rgba(theme.colors.black, 0.35),
|
background: rgba(theme.colors.black, 0.35),
|
||||||
backdropFilter: 'blur(0.25em)',
|
backdropFilter: 'blur(0.1em)',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import { IoAdd } from 'react-icons/io5';
|
|||||||
import { MdOutlineAdminPanelSettings } from 'react-icons/md';
|
import { MdOutlineAdminPanelSettings } from 'react-icons/md';
|
||||||
import FavoriteList from '~/components/dashboard/side_nav/favorite/favorite_list';
|
import FavoriteList from '~/components/dashboard/side_nav/favorite/favorite_list';
|
||||||
import { Item, ItemLink } from '~/components/dashboard/side_nav/nav_item';
|
import { Item, ItemLink } from '~/components/dashboard/side_nav/nav_item';
|
||||||
import OpenSettingsButton from '~/components/dashboard/side_nav/open_settings';
|
|
||||||
import UserCard from '~/components/dashboard/side_nav/user_card';
|
import UserCard from '~/components/dashboard/side_nav/user_card';
|
||||||
|
import ModalSettings from '~/components/settings/modal';
|
||||||
import useActiveCollection from '~/hooks/use_active_collection';
|
import useActiveCollection from '~/hooks/use_active_collection';
|
||||||
import { appendCollectionId } from '~/lib/navigation';
|
import { appendCollectionId } from '~/lib/navigation';
|
||||||
|
|
||||||
@@ -21,6 +21,10 @@ const AdminButton = styled(Item)(({ theme }) => ({
|
|||||||
color: theme.colors.lightRed,
|
color: theme.colors.lightRed,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const SettingsButton = styled(Item)(({ theme }) => ({
|
||||||
|
color: theme.colors.grey,
|
||||||
|
}));
|
||||||
|
|
||||||
const AddButton = styled(ItemLink)(({ theme }) => ({
|
const AddButton = styled(ItemLink)(({ theme }) => ({
|
||||||
color: theme.colors.primary,
|
color: theme.colors.primary,
|
||||||
}));
|
}));
|
||||||
@@ -34,7 +38,7 @@ export default function SideNavigation() {
|
|||||||
<AdminButton>
|
<AdminButton>
|
||||||
<MdOutlineAdminPanelSettings /> Administrator
|
<MdOutlineAdminPanelSettings /> Administrator
|
||||||
</AdminButton>
|
</AdminButton>
|
||||||
<OpenSettingsButton />
|
<ModalSettings openItem={SettingsButton} />
|
||||||
<AddButton
|
<AddButton
|
||||||
href={appendCollectionId(
|
href={appendCollectionId(
|
||||||
route('link.create-form').url,
|
route('link.create-form').url,
|
||||||
|
|||||||
@@ -3,11 +3,14 @@ import { Link } from '@inertiajs/react';
|
|||||||
import { route } from '@izzyjs/route/client';
|
import { route } from '@izzyjs/route/client';
|
||||||
import { IoIosLogOut } from 'react-icons/io';
|
import { IoIosLogOut } from 'react-icons/io';
|
||||||
import Dropdown from '~/components/common/dropdown/dropdown';
|
import Dropdown from '~/components/common/dropdown/dropdown';
|
||||||
import { DropdownItemLink } from '~/components/common/dropdown/dropdown_item';
|
import {
|
||||||
|
DropdownItemButton,
|
||||||
|
DropdownItemLink,
|
||||||
|
} from '~/components/common/dropdown/dropdown_item';
|
||||||
import ExternalLink from '~/components/common/external_link';
|
import ExternalLink from '~/components/common/external_link';
|
||||||
import RoundedImage from '~/components/common/rounded_image';
|
import RoundedImage from '~/components/common/rounded_image';
|
||||||
import UnstyledList from '~/components/common/unstyled/unstyled_list';
|
import UnstyledList from '~/components/common/unstyled/unstyled_list';
|
||||||
import useDarkTheme from '~/hooks/use_dark_theme';
|
import ModalSettings from '~/components/settings/modal';
|
||||||
import useUser from '~/hooks/use_user';
|
import useUser from '~/hooks/use_user';
|
||||||
import PATHS from '../../../app/constants/paths';
|
import PATHS from '../../../app/constants/paths';
|
||||||
|
|
||||||
@@ -57,14 +60,6 @@ export default function Navbar() {
|
|||||||
</li>
|
</li>
|
||||||
</NavList>
|
</NavList>
|
||||||
<NavList right>
|
<NavList right>
|
||||||
<li>
|
|
||||||
<select>
|
|
||||||
<option>EN</option>
|
|
||||||
</select>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<ThemeSwitch />
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<ExternalLink href={PATHS.REPO_GITHUB}>GitHub</ExternalLink>
|
<ExternalLink href={PATHS.REPO_GITHUB}>GitHub</ExternalLink>
|
||||||
</li>
|
</li>
|
||||||
@@ -74,22 +69,7 @@ export default function Navbar() {
|
|||||||
<Link href={route('dashboard').url}>Dashboard</Link>
|
<Link href={route('dashboard').url}>Dashboard</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Dropdown
|
<ProfileDropdown />
|
||||||
label={
|
|
||||||
<UserCard>
|
|
||||||
<RoundedImage
|
|
||||||
src={user.avatarUrl}
|
|
||||||
width={22}
|
|
||||||
referrerPolicy="no-referrer"
|
|
||||||
/>
|
|
||||||
{user.nickName}
|
|
||||||
</UserCard>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<DropdownItemLink href={route('auth.logout').url} danger>
|
|
||||||
<IoIosLogOut /> Logout
|
|
||||||
</DropdownItemLink>
|
|
||||||
</Dropdown>
|
|
||||||
</li>
|
</li>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
@@ -102,13 +82,25 @@ export default function Navbar() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ThemeSwitch() {
|
function ProfileDropdown() {
|
||||||
const { isDarkTheme, toggleDarkTheme } = useDarkTheme();
|
const { user } = useUser();
|
||||||
return (
|
return (
|
||||||
<input
|
<Dropdown
|
||||||
type="checkbox"
|
label={
|
||||||
onChange={({ target }) => toggleDarkTheme(target.checked)}
|
<UserCard>
|
||||||
checked={isDarkTheme}
|
<RoundedImage
|
||||||
/>
|
src={user!.avatarUrl}
|
||||||
|
width={22}
|
||||||
|
referrerPolicy="no-referrer"
|
||||||
|
/>
|
||||||
|
{user!.nickName}
|
||||||
|
</UserCard>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ModalSettings openItem={DropdownItemButton} />
|
||||||
|
<DropdownItemLink href={route('auth.logout').url} danger>
|
||||||
|
<IoIosLogOut /> Logout
|
||||||
|
</DropdownItemLink>
|
||||||
|
</Dropdown>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,29 @@
|
|||||||
import styled from '@emotion/styled';
|
|
||||||
import { BsGear } from 'react-icons/bs';
|
import { BsGear } from 'react-icons/bs';
|
||||||
import Modal from '~/components/common/modal/modal';
|
import Modal from '~/components/common/modal/modal';
|
||||||
import { Item } from '~/components/dashboard/side_nav/nav_item';
|
import ThemeSwitcher from '~/components/theme_switcher';
|
||||||
import useToggle from '~/hooks/use_modal';
|
import useToggle from '~/hooks/use_modal';
|
||||||
|
|
||||||
const SettingsButton = styled(Item)(({ theme }) => ({
|
export default function ModalSettings({
|
||||||
color: theme.colors.grey,
|
openItem: OpenItem,
|
||||||
}));
|
}: {
|
||||||
|
// TODO: fix this :()
|
||||||
export default function OpenSettingsButton() {
|
openItem: any;
|
||||||
|
}) {
|
||||||
const { isShowing, open, close } = useToggle();
|
const { isShowing, open, close } = useToggle();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SettingsButton onClick={open}>
|
<OpenItem onClick={open}>
|
||||||
<BsGear />
|
<BsGear />
|
||||||
Settings
|
Settings
|
||||||
</SettingsButton>
|
</OpenItem>
|
||||||
<Modal title="Settings" opened={isShowing} close={close}>
|
<Modal title="Settings" opened={isShowing} close={close}>
|
||||||
Modal settings
|
Modal settings
|
||||||
|
<hr />
|
||||||
|
<select>
|
||||||
|
<option>EN</option>
|
||||||
|
</select>
|
||||||
|
<hr />
|
||||||
|
<ThemeSwitcher />
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
25
inertia/components/theme_switcher.tsx
Normal file
25
inertia/components/theme_switcher.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { Fragment } from 'react';
|
||||||
|
import Toggle from 'react-toggle';
|
||||||
|
import 'react-toggle/style.css';
|
||||||
|
import useDarkTheme from '~/hooks/use_dark_theme';
|
||||||
|
|
||||||
|
export default function ThemeSwitcher() {
|
||||||
|
const { isDarkTheme, toggleDarkTheme } = useDarkTheme();
|
||||||
|
|
||||||
|
if (typeof window === 'undefined') {
|
||||||
|
return <Fragment />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Toggle
|
||||||
|
onChange={({ target }) => toggleDarkTheme(target.checked)}
|
||||||
|
checked={isDarkTheme}
|
||||||
|
name="theme-switcher"
|
||||||
|
id="theme-switcher"
|
||||||
|
icons={{
|
||||||
|
checked: '☀️',
|
||||||
|
unchecked: '🌑',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
50
package-lock.json
generated
50
package-lock.json
generated
@@ -38,6 +38,7 @@
|
|||||||
"react-i18next": "^14.1.1",
|
"react-i18next": "^14.1.1",
|
||||||
"react-icons": "^5.1.0",
|
"react-icons": "^5.1.0",
|
||||||
"react-swipeable": "^7.0.1",
|
"react-swipeable": "^7.0.1",
|
||||||
|
"react-toggle": "^4.1.3",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
"uuid": "^9.0.1"
|
"uuid": "^9.0.1"
|
||||||
},
|
},
|
||||||
@@ -55,6 +56,7 @@
|
|||||||
"@types/node": "^20.12.7",
|
"@types/node": "^20.12.7",
|
||||||
"@types/react": "^18.3.1",
|
"@types/react": "^18.3.1",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
|
"@types/react-toggle": "^4.0.5",
|
||||||
"@types/uuid": "^9.0.8",
|
"@types/uuid": "^9.0.8",
|
||||||
"@vitejs/plugin-react": "^4.2.1",
|
"@vitejs/plugin-react": "^4.2.1",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
@@ -2993,6 +2995,15 @@
|
|||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/react-toggle": {
|
||||||
|
"version": "4.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-toggle/-/react-toggle-4.0.5.tgz",
|
||||||
|
"integrity": "sha512-MHHEDe7GnF/EhLtI5sT70Dqab8rwlgjRZtu/u6gmfbYd+HeYxWiUSRog16+1BCfkz7Wy2VU6+TPU2oCsDtqDzA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/semver": {
|
"node_modules/@types/semver": {
|
||||||
"version": "7.5.8",
|
"version": "7.5.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
|
||||||
@@ -8060,6 +8071,15 @@
|
|||||||
"url": "https://github.com/fb55/nth-check?sponsor=1"
|
"url": "https://github.com/fb55/nth-check?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/object-assign": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-inspect": {
|
"node_modules/object-inspect": {
|
||||||
"version": "1.13.1",
|
"version": "1.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
|
||||||
@@ -8795,6 +8815,23 @@
|
|||||||
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz",
|
||||||
"integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ=="
|
"integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/prop-types": {
|
||||||
|
"version": "15.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||||
|
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.4.0",
|
||||||
|
"object-assign": "^4.1.1",
|
||||||
|
"react-is": "^16.13.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/prop-types/node_modules/react-is": {
|
||||||
|
"version": "16.13.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/property-information": {
|
"node_modules/property-information": {
|
||||||
"version": "6.5.0",
|
"version": "6.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz",
|
||||||
@@ -9041,6 +9078,19 @@
|
|||||||
"react": "^16.8.3 || ^17 || ^18"
|
"react": "^16.8.3 || ^17 || ^18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-toggle": {
|
||||||
|
"version": "4.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-toggle/-/react-toggle-4.1.3.tgz",
|
||||||
|
"integrity": "sha512-WoPrvbwfQSvoagbrDnXPrlsxwzuhQIrs+V0I162j/s+4XPgY/YDAUmHSeWiroznfI73wj+MBydvW95zX8ABbSg==",
|
||||||
|
"dependencies": {
|
||||||
|
"classnames": "^2.2.5"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"prop-types": ">= 15.3.0 < 19",
|
||||||
|
"react": ">= 15.3.0 < 19",
|
||||||
|
"react-dom": ">= 15.3.0 < 19"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/read-package-up": {
|
"node_modules/read-package-up": {
|
||||||
"version": "11.0.0",
|
"version": "11.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz",
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
"@types/node": "^20.12.7",
|
"@types/node": "^20.12.7",
|
||||||
"@types/react": "^18.3.1",
|
"@types/react": "^18.3.1",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
|
"@types/react-toggle": "^4.0.5",
|
||||||
"@types/uuid": "^9.0.8",
|
"@types/uuid": "^9.0.8",
|
||||||
"@vitejs/plugin-react": "^4.2.1",
|
"@vitejs/plugin-react": "^4.2.1",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
@@ -89,6 +90,7 @@
|
|||||||
"react-i18next": "^14.1.1",
|
"react-i18next": "^14.1.1",
|
||||||
"react-icons": "^5.1.0",
|
"react-icons": "^5.1.0",
|
||||||
"react-swipeable": "^7.0.1",
|
"react-swipeable": "^7.0.1",
|
||||||
|
"react-toggle": "^4.1.3",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
"uuid": "^9.0.1"
|
"uuid": "^9.0.1"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user