mirror of
https://github.com/Sonny93/my-links.git
synced 2025-12-10 07:25:35 +00:00
feat: add dropdown for links and collection header
This commit is contained in:
@@ -6,18 +6,33 @@ import type { HttpContext } from '@adonisjs/core/http';
|
|||||||
|
|
||||||
export default class CollectionsController {
|
export default class CollectionsController {
|
||||||
// Dashboard
|
// Dashboard
|
||||||
async index({ auth, inertia, response }: HttpContext) {
|
async index({ auth, inertia, request, response }: HttpContext) {
|
||||||
const collections = await this.getCollectionByAuthorId(auth.user!.id);
|
const collections = await this.getCollectionByAuthorId(auth.user!.id);
|
||||||
if (collections.length === 0) {
|
if (collections.length === 0) {
|
||||||
return response.redirect('/collections/create');
|
return response.redirect('/collections/create');
|
||||||
}
|
}
|
||||||
|
|
||||||
return inertia.render('dashboard', { collections });
|
const activeCollectionId = request.qs()?.collectionId ?? '';
|
||||||
|
const activeCollection = collections.find(
|
||||||
|
(c) => c.id === activeCollectionId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!activeCollection && !!activeCollectionId) {
|
||||||
|
return response.redirect('/dashboard');
|
||||||
|
}
|
||||||
|
|
||||||
|
return inertia.render('dashboard', {
|
||||||
|
collections,
|
||||||
|
activeCollection: activeCollection || collections[0],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create collection form
|
// Create collection form
|
||||||
async showCreatePage({ inertia }: HttpContext) {
|
async showCreatePage({ inertia, auth }: HttpContext) {
|
||||||
return inertia.render('collections/create');
|
const collections = await this.getCollectionByAuthorId(auth.user!.id);
|
||||||
|
return inertia.render('collections/create', {
|
||||||
|
disableHomeLink: collections.length === 0,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method called when creating a collection
|
// Method called when creating a collection
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ export default defineConfig({
|
|||||||
sharedData: {
|
sharedData: {
|
||||||
errors: (ctx) => ctx.session?.flashMessages.get('errors'),
|
errors: (ctx) => ctx.session?.flashMessages.get('errors'),
|
||||||
auth: async (ctx) => {
|
auth: async (ctx) => {
|
||||||
await ctx.auth.check();
|
await ctx.auth?.check();
|
||||||
return {
|
return {
|
||||||
user: ctx.auth.user,
|
user: ctx.auth?.user || null,
|
||||||
isAuthenticated: ctx.auth.isAuthenticated,
|
isAuthenticated: ctx.auth?.isAuthenticated || false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -32,9 +32,11 @@ const DropdownStyle = styled.div<{ opened: boolean }>(({ opened, theme }) => ({
|
|||||||
export default function Dropdown({
|
export default function Dropdown({
|
||||||
children,
|
children,
|
||||||
label,
|
label,
|
||||||
|
className,
|
||||||
}: {
|
}: {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
label: ReactNode | string;
|
label: ReactNode | string;
|
||||||
|
className?: string;
|
||||||
}) {
|
}) {
|
||||||
const dropdownRef = useRef<HTMLDivElement>(null);
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
||||||
const { isShowing, toggle, close } = useToggle();
|
const { isShowing, toggle, close } = useToggle();
|
||||||
@@ -48,7 +50,12 @@ export default function Dropdown({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownStyle opened={isShowing} onClick={toggle} ref={dropdownRef}>
|
<DropdownStyle
|
||||||
|
opened={isShowing}
|
||||||
|
onClick={toggle}
|
||||||
|
ref={dropdownRef}
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
<DropdownLabel>{label}</DropdownLabel>
|
<DropdownLabel>{label}</DropdownLabel>
|
||||||
<DropdownContainer show={isShowing}>{children}</DropdownContainer>
|
<DropdownContainer show={isShowing}>{children}</DropdownContainer>
|
||||||
</DropdownStyle>
|
</DropdownStyle>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
const DropdownContainer = styled.div<{ show: boolean }>(({ show, theme }) => ({
|
const DropdownContainer = styled.div<{ show: boolean }>(({ show, theme }) => ({
|
||||||
|
zIndex: 99,
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: 'calc(100% + 0.5em)',
|
top: 'calc(100% + 0.5em)',
|
||||||
right: 0,
|
right: 0,
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { Link } from '@inertiajs/react';
|
||||||
|
|
||||||
const DropdownItem = styled.div(({ theme }) => ({
|
const DropdownItemBase = styled.div(({ theme }) => ({
|
||||||
fontSize: '14px',
|
fontSize: '14px',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
padding: '8px 12px',
|
padding: '8px 12px',
|
||||||
display: 'flex',
|
|
||||||
gap: '0.35em',
|
|
||||||
alignItems: 'center',
|
|
||||||
borderRadius: theme.border.radius,
|
borderRadius: theme.border.radius,
|
||||||
|
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
@@ -13,4 +12,17 @@ const DropdownItem = styled.div(({ theme }) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default DropdownItem;
|
const DropdownItemButton = styled(DropdownItemBase)({
|
||||||
|
display: 'flex',
|
||||||
|
gap: '0.75em',
|
||||||
|
alignItems: 'center',
|
||||||
|
});
|
||||||
|
|
||||||
|
const DropdownItemLink = styled(DropdownItemBase.withComponent(Link))({
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
gap: '0.75em',
|
||||||
|
alignItems: 'center',
|
||||||
|
});
|
||||||
|
|
||||||
|
export { DropdownItemButton, DropdownItemLink };
|
||||||
|
|||||||
@@ -1,34 +1,28 @@
|
|||||||
|
import PATHS from '#constants/paths';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import QuickResourceAction from '~/components/dashboard/quick_action/quick_action';
|
import { BsThreeDotsVertical } from 'react-icons/bs';
|
||||||
import useActiveCollection from '~/hooks/use_active_collection';
|
import { HiOutlinePencil } from 'react-icons/hi2';
|
||||||
|
import { IoIosAddCircleOutline } from 'react-icons/io';
|
||||||
|
import { IoTrashOutline } from 'react-icons/io5';
|
||||||
|
import Dropdown from '~/components/common/dropdown/dropdown';
|
||||||
|
import { DropdownItemLink } from '~/components/common/dropdown/dropdown_item';
|
||||||
|
|
||||||
const CollectionControlsStyle = styled.span({
|
const DeleteItem = styled(DropdownItemLink)(({ theme }) => ({
|
||||||
display: 'flex',
|
color: theme.colors.lightRed,
|
||||||
gap: '0.5em',
|
}));
|
||||||
alignItems: 'center',
|
|
||||||
});
|
|
||||||
|
|
||||||
export default function CollectionControls() {
|
const CollectionControls = () => (
|
||||||
const { activeCollection } = useActiveCollection();
|
<Dropdown label={<BsThreeDotsVertical />}>
|
||||||
return (
|
<DropdownItemLink href={PATHS.LINK.CREATE}>
|
||||||
activeCollection && (
|
<IoIosAddCircleOutline /> Add
|
||||||
<CollectionControlsStyle>
|
</DropdownItemLink>
|
||||||
<QuickResourceAction
|
<DropdownItemLink href={PATHS.COLLECTION.EDIT}>
|
||||||
resource="link"
|
<HiOutlinePencil /> Edit
|
||||||
action="create"
|
</DropdownItemLink>
|
||||||
collectionId={activeCollection.id}
|
<DeleteItem href={PATHS.COLLECTION.REMOVE}>
|
||||||
/>
|
<IoTrashOutline /> Delete
|
||||||
<QuickResourceAction
|
</DeleteItem>
|
||||||
resource="collection"
|
</Dropdown>
|
||||||
action="edit"
|
);
|
||||||
resourceId={activeCollection.id}
|
|
||||||
/>
|
export default CollectionControls;
|
||||||
<QuickResourceAction
|
|
||||||
resource="collection"
|
|
||||||
action="remove"
|
|
||||||
resourceId={activeCollection.id}
|
|
||||||
/>
|
|
||||||
</CollectionControlsStyle>
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|||||||
98
inertia/components/dashboard/link_list/link_controls.tsx
Normal file
98
inertia/components/dashboard/link_list/link_controls.tsx
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
import PATHS from '#constants/paths';
|
||||||
|
import type Link from '#models/link';
|
||||||
|
import { useTheme } from '@emotion/react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import { AiFillStar, AiOutlineStar } from 'react-icons/ai';
|
||||||
|
import { BsThreeDotsVertical } from 'react-icons/bs';
|
||||||
|
import { HiOutlinePencil } from 'react-icons/hi2';
|
||||||
|
import { IoTrashOutline } from 'react-icons/io5';
|
||||||
|
import Dropdown from '~/components/common/dropdown/dropdown';
|
||||||
|
import {
|
||||||
|
DropdownItemButton,
|
||||||
|
DropdownItemLink,
|
||||||
|
} from '~/components/common/dropdown/dropdown_item';
|
||||||
|
import useCollections from '~/hooks/use_collections';
|
||||||
|
import { appendCollectionId } from '~/lib/navigation';
|
||||||
|
import { makeRequest } from '~/lib/request';
|
||||||
|
|
||||||
|
const StartItem = styled(DropdownItemButton)(({ theme }) => ({
|
||||||
|
color: theme.colors.yellow,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const DeleteItem = styled(DropdownItemLink)(({ theme }) => ({
|
||||||
|
color: theme.colors.lightRed,
|
||||||
|
}));
|
||||||
|
|
||||||
|
export default function LinkControls({ link }: { link: Link }) {
|
||||||
|
const theme = useTheme();
|
||||||
|
const { collections, setCollections } = useCollections();
|
||||||
|
|
||||||
|
const toggleFavorite = useCallback(
|
||||||
|
(linkId: Link['id']) => {
|
||||||
|
let linkIndex = 0;
|
||||||
|
const collectionIndex = collections.findIndex(({ links }) => {
|
||||||
|
const lIndex = links.findIndex((l) => l.id === linkId);
|
||||||
|
if (lIndex !== -1) {
|
||||||
|
linkIndex = lIndex;
|
||||||
|
}
|
||||||
|
return lIndex !== -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
const collectionLink = collections[collectionIndex].links[linkIndex];
|
||||||
|
const collectionsCopy = [...collections];
|
||||||
|
collectionsCopy[collectionIndex].links[linkIndex] = {
|
||||||
|
...collectionLink,
|
||||||
|
favorite: !collectionLink.favorite,
|
||||||
|
};
|
||||||
|
|
||||||
|
setCollections(collectionsCopy);
|
||||||
|
},
|
||||||
|
[collections, setCollections]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onFavorite = () => {
|
||||||
|
makeRequest({
|
||||||
|
url: `${PATHS.API.LINK}/${link.id}`,
|
||||||
|
method: 'PUT',
|
||||||
|
body: {
|
||||||
|
name: link.name,
|
||||||
|
url: link.url,
|
||||||
|
favorite: !link.favorite,
|
||||||
|
collectionId: link.collectionId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => toggleFavorite(link.id))
|
||||||
|
.catch(console.error);
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(link.favorite, link.favorite ? 'oui' : 'non');
|
||||||
|
return (
|
||||||
|
<Dropdown
|
||||||
|
label={<BsThreeDotsVertical />}
|
||||||
|
css={{ backgroundColor: theme.colors.secondary }}
|
||||||
|
>
|
||||||
|
<StartItem onClick={onFavorite}>
|
||||||
|
{!link.favorite ? (
|
||||||
|
<>
|
||||||
|
<AiFillStar /> Add to favorites
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<AiOutlineStar /> Remove from favorites
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</StartItem>
|
||||||
|
<DropdownItemLink
|
||||||
|
href={appendCollectionId(PATHS.LINK.EDIT, link.collectionId)}
|
||||||
|
>
|
||||||
|
<HiOutlinePencil /> Edit
|
||||||
|
</DropdownItemLink>
|
||||||
|
<DeleteItem
|
||||||
|
href={appendCollectionId(PATHS.LINK.REMOVE, link.collectionId)}
|
||||||
|
>
|
||||||
|
<IoTrashOutline /> Delete
|
||||||
|
</DeleteItem>
|
||||||
|
</Dropdown>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,14 +1,9 @@
|
|||||||
import PATHS from '#constants/paths';
|
|
||||||
import type Link from '#models/link';
|
import type Link from '#models/link';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useCallback } from 'react';
|
|
||||||
import { AiFillStar } from 'react-icons/ai';
|
import { AiFillStar } from 'react-icons/ai';
|
||||||
import ExternalLink from '~/components/common/external_link';
|
import ExternalLink from '~/components/common/external_link';
|
||||||
import LinkFavicon from '~/components/dashboard/link/link_favicon';
|
import LinkFavicon from '~/components/dashboard/link/link_favicon';
|
||||||
import QuickResourceAction from '~/components/dashboard/quick_action/quick_action';
|
import LinkControls from '~/components/dashboard/link_list/link_controls';
|
||||||
import QuickLinkFavorite from '~/components/dashboard/quick_action/quick_favorite_link';
|
|
||||||
import useCollections from '~/hooks/use_collections';
|
|
||||||
import { makeRequest } from '~/lib/request';
|
|
||||||
|
|
||||||
const LinkWrapper = styled.li(({ theme }) => ({
|
const LinkWrapper = styled.li(({ theme }) => ({
|
||||||
userSelect: 'none',
|
userSelect: 'none',
|
||||||
@@ -20,16 +15,21 @@ const LinkWrapper = styled.li(({ theme }) => ({
|
|||||||
padding: '0.75em 1em',
|
padding: '0.75em 1em',
|
||||||
border: `1px solid ${theme.colors.lightGrey}`,
|
border: `1px solid ${theme.colors.lightGrey}`,
|
||||||
borderRadius: theme.border.radius,
|
borderRadius: theme.border.radius,
|
||||||
outline: '3px solid transparent',
|
|
||||||
|
'&:hover': {
|
||||||
|
outlineWidth: '1px',
|
||||||
|
outlineStyle: 'solid',
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const LinkHeader = styled.div(({ theme }) => ({
|
const LinkHeader = styled.div(({ theme }) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
gap: '1em',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
|
||||||
'& > a': {
|
'& > a': {
|
||||||
height: '100%',
|
height: '100%',
|
||||||
maxWidth: 'calc(100% - 125px)', // TODO: fix this, it is ugly af :(
|
maxWidth: 'calc(100% - 75px)', // TODO: fix this, it is ugly af :(
|
||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flex: 1,
|
flex: 1,
|
||||||
@@ -49,22 +49,6 @@ const LinkName = styled.div({
|
|||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
});
|
});
|
||||||
|
|
||||||
const LinkControls = styled.div({
|
|
||||||
display: 'none',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
gap: '10px',
|
|
||||||
|
|
||||||
'& svg': {
|
|
||||||
height: '20px',
|
|
||||||
width: '20px',
|
|
||||||
},
|
|
||||||
|
|
||||||
'&:hover *': {
|
|
||||||
transform: 'scale(1.3)',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const LinkDescription = styled.div(({ theme }) => ({
|
const LinkDescription = styled.div(({ theme }) => ({
|
||||||
marginTop: '0.5em',
|
marginTop: '0.5em',
|
||||||
color: theme.colors.font,
|
color: theme.colors.font,
|
||||||
@@ -97,46 +81,6 @@ export default function LinkItem({
|
|||||||
showUserControls: boolean;
|
showUserControls: boolean;
|
||||||
}) {
|
}) {
|
||||||
const { id, name, url, description, favorite } = link;
|
const { id, name, url, description, favorite } = link;
|
||||||
const { collections, setCollections } = useCollections();
|
|
||||||
|
|
||||||
const toggleFavorite = useCallback(
|
|
||||||
(linkId: Link['id']) => {
|
|
||||||
let linkIndex = 0;
|
|
||||||
const collectionIndex = collections.findIndex(({ links }) => {
|
|
||||||
const lIndex = links.findIndex((l) => l.id === linkId);
|
|
||||||
if (lIndex !== -1) {
|
|
||||||
linkIndex = lIndex;
|
|
||||||
}
|
|
||||||
return lIndex !== -1;
|
|
||||||
});
|
|
||||||
|
|
||||||
const collectionLink = collections[collectionIndex].links[linkIndex];
|
|
||||||
const collectionsCopy = [...collections];
|
|
||||||
collectionsCopy[collectionIndex].links[linkIndex] = {
|
|
||||||
...collectionLink,
|
|
||||||
favorite: !collectionLink.favorite,
|
|
||||||
};
|
|
||||||
|
|
||||||
setCollections(collectionsCopy);
|
|
||||||
},
|
|
||||||
[collections, setCollections]
|
|
||||||
);
|
|
||||||
|
|
||||||
const onFavorite = () => {
|
|
||||||
makeRequest({
|
|
||||||
url: `${PATHS.API.LINK}/${link.id}`,
|
|
||||||
method: 'PUT',
|
|
||||||
body: {
|
|
||||||
name,
|
|
||||||
url,
|
|
||||||
favorite: !favorite,
|
|
||||||
collectionId: link.collectionId,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then(() => toggleFavorite(link.id))
|
|
||||||
.catch(console.error);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LinkWrapper key={id}>
|
<LinkWrapper key={id}>
|
||||||
<LinkHeader>
|
<LinkHeader>
|
||||||
@@ -147,21 +91,7 @@ export default function LinkItem({
|
|||||||
</LinkName>
|
</LinkName>
|
||||||
<LinkItemURL url={url} />
|
<LinkItemURL url={url} />
|
||||||
</ExternalLink>
|
</ExternalLink>
|
||||||
{showUserControls && (
|
{showUserControls && <LinkControls link={link} />}
|
||||||
<LinkControls>
|
|
||||||
<QuickLinkFavorite onClick={onFavorite} isFavorite={favorite} />
|
|
||||||
<QuickResourceAction
|
|
||||||
resource="link"
|
|
||||||
action="edit"
|
|
||||||
resourceId={id}
|
|
||||||
/>
|
|
||||||
<QuickResourceAction
|
|
||||||
resource="link"
|
|
||||||
action="remove"
|
|
||||||
resourceId={id}
|
|
||||||
/>
|
|
||||||
</LinkControls>
|
|
||||||
)}
|
|
||||||
</LinkHeader>
|
</LinkHeader>
|
||||||
{description && <LinkDescription>{description}</LinkDescription>}
|
{description && <LinkDescription>{description}</LinkDescription>}
|
||||||
</LinkWrapper>
|
</LinkWrapper>
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ const LinksWrapper = styled.div({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const CollectionHeaderWrapper = styled.h2(({ theme }) => ({
|
const CollectionHeaderWrapper = styled.h2(({ theme }) => ({
|
||||||
|
fontWeight: 400,
|
||||||
color: theme.colors.primary,
|
color: theme.colors.primary,
|
||||||
fontWeight: 500,
|
paddingInline: '1em',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
gap: '0.4em',
|
gap: '0.4em',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ const FooterStyle = styled.footer(({ theme }) => ({
|
|||||||
color: theme.colors.grey,
|
color: theme.colors.grey,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
paddingTop: '0.75em',
|
paddingTop: '0.75em',
|
||||||
|
'& a:hover': {
|
||||||
|
textDecoration: 'underline',
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
import Footer from '~/components/footer/footer';
|
||||||
import Navbar from '../navbar/navbar';
|
import Navbar from '../navbar/navbar';
|
||||||
import BaseLayout from './_base_layout';
|
import BaseLayout from './_base_layout';
|
||||||
|
|
||||||
const ContentLayoutStyle = styled.div(({ theme }) => ({
|
const ContentLayoutStyle = styled.div(({ theme }) => ({
|
||||||
height: 'auto',
|
height: '100%',
|
||||||
width: theme.media.small_desktop,
|
width: theme.media.small_desktop,
|
||||||
maxWidth: '100%',
|
maxWidth: '100%',
|
||||||
padding: '1em',
|
padding: '1em',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
|
||||||
|
'& main': {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const ContentLayout = ({ children }: { children: ReactNode }) => (
|
const ContentLayout = ({ children }: { children: ReactNode }) => (
|
||||||
@@ -15,6 +22,7 @@ const ContentLayout = ({ children }: { children: ReactNode }) => (
|
|||||||
<ContentLayoutStyle>
|
<ContentLayoutStyle>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<main>{children}</main>
|
<main>{children}</main>
|
||||||
|
<Footer />
|
||||||
</ContentLayoutStyle>
|
</ContentLayoutStyle>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import PATHS from '#constants/paths';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { Link } from '@inertiajs/react';
|
import { Link } from '@inertiajs/react';
|
||||||
import { FormEvent, ReactNode } from 'react';
|
import { FormEvent, ReactNode } from 'react';
|
||||||
import Button from '~/components/common/form/_button';
|
import Button from '~/components/common/form/_button';
|
||||||
import Form from '~/components/common/form/_form';
|
import Form from '~/components/common/form/_form';
|
||||||
import BaseLayout from './_base_layout';
|
import BaseLayout from './_base_layout';
|
||||||
|
import { appendCollectionId } from '~/lib/navigation';
|
||||||
|
import PATHS from '#constants/paths';
|
||||||
|
|
||||||
const FormLayoutStyle = styled.div(({ theme }) => ({
|
const FormLayoutStyle = styled.div(({ theme }) => ({
|
||||||
height: 'fit-content',
|
height: 'fit-content',
|
||||||
@@ -26,6 +27,7 @@ interface FormLayoutProps {
|
|||||||
textSubmitButton?: string;
|
textSubmitButton?: string;
|
||||||
|
|
||||||
disableHomeLink?: boolean;
|
disableHomeLink?: boolean;
|
||||||
|
collectionId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FormLayout = ({
|
const FormLayout = ({
|
||||||
@@ -35,6 +37,7 @@ const FormLayout = ({
|
|||||||
handleSubmit,
|
handleSubmit,
|
||||||
textSubmitButton = 'Confirm',
|
textSubmitButton = 'Confirm',
|
||||||
disableHomeLink = false,
|
disableHomeLink = false,
|
||||||
|
collectionId,
|
||||||
}: FormLayoutProps) => (
|
}: FormLayoutProps) => (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
<FormLayoutStyle>
|
<FormLayoutStyle>
|
||||||
@@ -46,8 +49,9 @@ const FormLayout = ({
|
|||||||
</Button>
|
</Button>
|
||||||
</Form>
|
</Form>
|
||||||
{!disableHomeLink && (
|
{!disableHomeLink && (
|
||||||
// <Link href={collectionId ? `/?collectionId=${collectionId}` : '/'}>{t('common:back-home')}</Link>
|
<Link href={appendCollectionId(PATHS.DASHBOARD, collectionId)}>
|
||||||
<Link href={PATHS.DASHBOARD}>← Revenir à l'accueil</Link>
|
← Back to home
|
||||||
|
</Link>
|
||||||
)}
|
)}
|
||||||
</FormLayoutStyle>
|
</FormLayoutStyle>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import type Collection from '#models/collection';
|
|||||||
|
|
||||||
export const appendCollectionId = (
|
export const appendCollectionId = (
|
||||||
url: string,
|
url: string,
|
||||||
collectionId?: Collection['id']
|
collectionId?: Collection['id'] | null | undefined
|
||||||
) => `${url}${collectionId && `?collectionId=${collectionId}`}}`;
|
) => `${url}${collectionId ? `?collectionId=${collectionId}` : ''}`;
|
||||||
|
|
||||||
export const appendResourceId = (url: string, resourceId?: string) =>
|
export const appendResourceId = (url: string, resourceId?: string) =>
|
||||||
`${url}${resourceId && `/${resourceId}`}}`;
|
`${url}${resourceId ? `/${resourceId}` : ''}`;
|
||||||
|
|
||||||
export function isValidHttpUrl(urlParam: string) {
|
export function isValidHttpUrl(urlParam: string) {
|
||||||
let url;
|
let url;
|
||||||
|
|||||||
Reference in New Issue
Block a user