Compare commits

...

2 Commits

Author SHA1 Message Date
Philipinho ac47eb8dbe fix page level comment on mobile
* add icon next to comment box
2026-03-14 00:52:40 +00:00
Philip Okugbe 65b89a1b24 fix email button (#2017) 2026-03-14 00:40:32 +00:00
10 changed files with 95 additions and 106 deletions
@@ -24,7 +24,12 @@ function CommentActions({
</Button> </Button>
)} )}
<Button size="compact-sm" loading={isLoading} onClick={onSave}> <Button
size="compact-sm"
loading={isLoading}
onClick={onSave}
onMouseDown={(e) => e.preventDefault()}
>
{t("Save")} {t("Save")}
</Button> </Button>
</Group> </Group>
@@ -27,6 +27,9 @@ import { extractPageSlugId } from "@/lib";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useGetSpaceBySlugQuery } from "@/features/space/queries/space-query.ts"; import { useGetSpaceBySlugQuery } from "@/features/space/queries/space-query.ts";
import { IconArrowUp, IconMessageOff } from "@tabler/icons-react"; import { IconArrowUp, IconMessageOff } from "@tabler/icons-react";
import { useAtom } from "jotai";
import { currentUserAtom } from "@/features/user/atoms/current-user-atom";
import { CustomAvatar } from "@/components/ui/custom-avatar.tsx";
function CommentListWithTabs() { function CommentListWithTabs() {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -345,6 +348,7 @@ const PageCommentInput = ({ onSave, isLoading }) => {
const [content, setContent] = useState(""); const [content, setContent] = useState("");
const { ref, focused } = useFocusWithin(); const { ref, focused } = useFocusWithin();
const commentEditorRef = useRef(null); const commentEditorRef = useRef(null);
const [currentUser] = useAtom(currentUserAtom);
const handleSave = useCallback(() => { const handleSave = useCallback(() => {
onSave(null, content); onSave(null, content);
@@ -363,19 +367,30 @@ const PageCommentInput = ({ onSave, isLoading }) => {
position: "relative", position: "relative",
}} }}
> >
<CommentEditor <Group wrap="nowrap" align="flex-start" gap="xs">
ref={commentEditorRef} <CustomAvatar
onUpdate={setContent} size="sm"
onSave={handleSave} avatarUrl={currentUser?.user?.avatarUrl}
editable={true} name={currentUser?.user?.name}
placeholder={t("Add a comment...")} style={{ flexShrink: 0, marginTop: 10 }}
/> />
<div style={{ flex: 1, minWidth: 0 }}>
<CommentEditor
ref={commentEditorRef}
onUpdate={setContent}
onSave={handleSave}
editable={true}
placeholder={t("Add a comment...")}
/>
</div>
</Group>
{focused && ( {focused && (
<ActionIcon <ActionIcon
variant="filled" variant="filled"
radius="xl" radius="xl"
size="sm" size="sm"
onClick={handleSave} onClick={handleSave}
onMouseDown={(e) => e.preventDefault()}
loading={isLoading} loading={isLoading}
style={{ position: "absolute", right: 8, bottom: 30 }} style={{ position: "absolute", right: 8, bottom: 30 }}
> >
@@ -1,7 +1,7 @@
import { Section, Text, Button } from '@react-email/components'; import { Section, Text } from '@react-email/components';
import * as React from 'react'; import * as React from 'react';
import { button, content, paragraph } from '../css/styles'; import { content, paragraph } from '../css/styles';
import { MailBody } from '../partials/partials'; import { EmailButton, MailBody } from '../partials/partials';
interface Props { interface Props {
actorName: string; actorName: string;
@@ -23,19 +23,7 @@ export const CommentCreateEmail = ({
<strong>{pageTitle}</strong>. <strong>{pageTitle}</strong>.
</Text> </Text>
</Section> </Section>
<Section <EmailButton href={pageUrl}>View</EmailButton>
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
paddingLeft: '15px',
paddingBottom: '15px',
}}
>
<Button href={pageUrl} style={button}>
View
</Button>
</Section>
</MailBody> </MailBody>
); );
}; };
@@ -1,7 +1,7 @@
import { Section, Text, Button } from '@react-email/components'; import { Section, Text } from '@react-email/components';
import * as React from 'react'; import * as React from 'react';
import { button, content, paragraph } from '../css/styles'; import { content, paragraph } from '../css/styles';
import { MailBody } from '../partials/partials'; import { EmailButton, MailBody } from '../partials/partials';
interface Props { interface Props {
actorName: string; actorName: string;
@@ -23,19 +23,7 @@ export const CommentMentionEmail = ({
<strong>{pageTitle}</strong>. <strong>{pageTitle}</strong>.
</Text> </Text>
</Section> </Section>
<Section <EmailButton href={pageUrl}>View</EmailButton>
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
paddingLeft: '15px',
paddingBottom: '15px',
}}
>
<Button href={pageUrl} style={button}>
View
</Button>
</Section>
</MailBody> </MailBody>
); );
}; };
@@ -1,7 +1,7 @@
import { Section, Text, Button } from '@react-email/components'; import { Section, Text } from '@react-email/components';
import * as React from 'react'; import * as React from 'react';
import { button, content, paragraph } from '../css/styles'; import { content, paragraph } from '../css/styles';
import { MailBody } from '../partials/partials'; import { EmailButton, MailBody } from '../partials/partials';
interface Props { interface Props {
actorName: string; actorName: string;
@@ -23,19 +23,7 @@ export const CommentResolvedEmail = ({
<strong>{pageTitle}</strong>. <strong>{pageTitle}</strong>.
</Text> </Text>
</Section> </Section>
<Section <EmailButton href={pageUrl}>View</EmailButton>
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
paddingLeft: '15px',
paddingBottom: '15px',
}}
>
<Button href={pageUrl} style={button}>
View
</Button>
</Section>
</MailBody> </MailBody>
); );
}; };
@@ -1,7 +1,7 @@
import { Section, Text, Button } from '@react-email/components'; import { Section, Text } from '@react-email/components';
import * as React from 'react'; import * as React from 'react';
import { button, content, paragraph } from '../css/styles'; import { content, paragraph } from '../css/styles';
import { MailBody } from '../partials/partials'; import { EmailButton, MailBody } from '../partials/partials';
interface Props { interface Props {
inviteLink: string; inviteLink: string;
@@ -17,19 +17,7 @@ export const InvitationEmail = ({ inviteLink }: Props) => {
Please click the button below to accept this invitation. Please click the button below to accept this invitation.
</Text> </Text>
</Section> </Section>
<Section <EmailButton href={inviteLink}>Accept Invite</EmailButton>
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
paddingLeft: '15px',
paddingBottom: '15px',
}}
>
<Button href={inviteLink} style={button}>
Accept Invite
</Button>
</Section>
</MailBody> </MailBody>
); );
}; };
@@ -1,7 +1,7 @@
import { Section, Text, Button } from '@react-email/components'; import { Section, Text } from '@react-email/components';
import * as React from 'react'; import * as React from 'react';
import { button, content, paragraph } from '../css/styles'; import { content, paragraph } from '../css/styles';
import { MailBody } from '../partials/partials'; import { EmailButton, MailBody } from '../partials/partials';
interface Props { interface Props {
actorName: string; actorName: string;
@@ -19,19 +19,7 @@ export const PageMentionEmail = ({ actorName, pageTitle, pageUrl }: Props) => {
<strong>{pageTitle}</strong>. <strong>{pageTitle}</strong>.
</Text> </Text>
</Section> </Section>
<Section <EmailButton href={pageUrl}>View</EmailButton>
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
paddingLeft: '15px',
paddingBottom: '15px',
}}
>
<Button href={pageUrl} style={button}>
View
</Button>
</Section>
</MailBody> </MailBody>
); );
}; };
@@ -1,7 +1,7 @@
import { Section, Text, Button } from '@react-email/components'; import { Section, Text } from '@react-email/components';
import * as React from 'react'; import * as React from 'react';
import { button, content, paragraph } from '../css/styles'; import { content, paragraph } from '../css/styles';
import { MailBody } from '../partials/partials'; import { EmailButton, MailBody } from '../partials/partials';
interface Props { interface Props {
actorName: string; actorName: string;
@@ -25,19 +25,7 @@ export const PermissionGrantedEmail = ({
<strong>{pageTitle}</strong>. <strong>{pageTitle}</strong>.
</Text> </Text>
</Section> </Section>
<Section <EmailButton href={pageUrl}>View</EmailButton>
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
paddingLeft: '15px',
paddingBottom: '15px',
}}
>
<Button href={pageUrl} style={button}>
View
</Button>
</Section>
</MailBody> </MailBody>
); );
}; };
@@ -1,4 +1,4 @@
import { container, footer, h1, logo, main } from '../css/styles'; import { button as buttonStyle, container, footer, h1, logo, main } from '../css/styles';
import { import {
Body, Body,
Container, Container,
@@ -35,6 +35,47 @@ export function MailHeader() {
); );
} }
interface EmailButtonProps {
href: string;
children: React.ReactNode;
}
export function EmailButton({ href, children }: EmailButtonProps) {
return (
<table
role="presentation"
cellPadding="0"
cellSpacing="0"
style={{ margin: '0 0 15px 15px' }}
>
<tr>
<td
style={{
backgroundColor: buttonStyle.backgroundColor,
borderRadius: buttonStyle.borderRadius,
textAlign: 'center' as const,
}}
>
<a
href={href}
target="_blank"
style={{
color: buttonStyle.color,
fontFamily: buttonStyle.fontFamily,
fontSize: buttonStyle.fontSize,
textDecoration: 'none',
display: 'inline-block',
padding: '8px 16px',
}}
>
{children}
</a>
</td>
</tr>
</table>
);
}
export function MailFooter() { export function MailFooter() {
return ( return (
<Section style={footer}> <Section style={footer}>