mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 20:13:49 +00:00
Style updates
This commit is contained in:
@@ -9,7 +9,7 @@ const BeerRecommendations: FunctionComponent<BeerRecommendationsProps> = ({
|
||||
beerRecommendations,
|
||||
}) => {
|
||||
return (
|
||||
<div className="card sticky top-2 h-full overflow-y-scroll bg-base-300">
|
||||
<div className="card sticky top-2 h-full overflow-y-scroll">
|
||||
<div className="card-body space-y-3">
|
||||
{beerRecommendations.map((beerPost) => (
|
||||
<div key={beerPost.id} className="w-full">
|
||||
|
||||
@@ -1,23 +1,10 @@
|
||||
import UserContext from '@/contexts/userContext';
|
||||
import useBeerPostComments from '@/hooks/useBeerPostComments';
|
||||
import useTimeDistance from '@/hooks/useTimeDistance';
|
||||
import BeerCommentQueryResult from '@/services/BeerComment/schema/BeerCommentQueryResult';
|
||||
import BeerCommentValidationSchema from '@/services/BeerComment/schema/CreateBeerCommentValidationSchema';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import format from 'date-fns/format';
|
||||
import Link from 'next/link';
|
||||
import { Dispatch, FC, SetStateAction, useContext, useEffect, useState } from 'react';
|
||||
import { Rating } from 'react-daisyui';
|
||||
import { SubmitHandler, useForm } from 'react-hook-form';
|
||||
|
||||
import { FaEllipsisH } from 'react-icons/fa';
|
||||
import { FC, useState } from 'react';
|
||||
import { useInView } from 'react-intersection-observer';
|
||||
import { z } from 'zod';
|
||||
import FormError from '../ui/forms/FormError';
|
||||
import FormInfo from '../ui/forms/FormInfo';
|
||||
import FormLabel from '../ui/forms/FormLabel';
|
||||
import FormSegment from '../ui/forms/FormSegment';
|
||||
import FormTextArea from '../ui/forms/FormTextArea';
|
||||
import CommentContentBody from './CommentContentBody';
|
||||
import EditCommentBody from './EditCommentBody';
|
||||
|
||||
interface CommentCardProps {
|
||||
comment: z.infer<typeof BeerCommentQueryResult>;
|
||||
@@ -25,269 +12,17 @@ interface CommentCardProps {
|
||||
ref?: ReturnType<typeof useInView>['ref'];
|
||||
}
|
||||
|
||||
interface CommentCardDropdownProps extends CommentCardProps {
|
||||
inEditMode: boolean;
|
||||
setInEditMode: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const CommentCardDropdown: FC<CommentCardDropdownProps> = ({
|
||||
comment,
|
||||
setInEditMode,
|
||||
}) => {
|
||||
const { user } = useContext(UserContext);
|
||||
|
||||
const isCommentOwner = user?.id === comment.postedBy.id;
|
||||
|
||||
return (
|
||||
<div className="dropdown-end dropdown">
|
||||
<label tabIndex={0} className="btn-ghost btn-sm btn m-1">
|
||||
<FaEllipsisH />
|
||||
</label>
|
||||
<ul
|
||||
tabIndex={0}
|
||||
className="dropdown-content menu rounded-box w-52 bg-base-100 p-2 shadow"
|
||||
>
|
||||
<li>
|
||||
{isCommentOwner ? (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setInEditMode(true);
|
||||
}}
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<button>Report</button>
|
||||
)}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const EditCommentBody: FC<CommentCardDropdownProps> = ({
|
||||
comment,
|
||||
setInEditMode,
|
||||
ref,
|
||||
mutate,
|
||||
}) => {
|
||||
const { register, handleSubmit, formState, setValue, watch } = useForm<
|
||||
z.infer<typeof BeerCommentValidationSchema>
|
||||
>({
|
||||
defaultValues: {
|
||||
content: comment.content,
|
||||
rating: comment.rating,
|
||||
},
|
||||
resolver: zodResolver(BeerCommentValidationSchema),
|
||||
});
|
||||
|
||||
const { errors } = formState;
|
||||
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
setIsDeleting(false);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleDelete = async () => {
|
||||
setIsDeleting(true);
|
||||
const response = await fetch(`/api/beer-comments/${comment.id}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to delete comment');
|
||||
}
|
||||
|
||||
await mutate();
|
||||
};
|
||||
|
||||
const onSubmit: SubmitHandler<z.infer<typeof BeerCommentValidationSchema>> = async (
|
||||
data,
|
||||
) => {
|
||||
const response = await fetch(`/api/beer-comments/${comment.id}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
content: data.content,
|
||||
rating: data.rating,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to update comment');
|
||||
}
|
||||
|
||||
await mutate();
|
||||
setInEditMode(false);
|
||||
};
|
||||
return (
|
||||
<div className="card-body animate-in fade-in-10" ref={ref}>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-3">
|
||||
<div>
|
||||
<FormInfo>
|
||||
<FormLabel htmlFor="content">Edit your comment</FormLabel>
|
||||
<FormError>{errors.content?.message}</FormError>
|
||||
</FormInfo>
|
||||
<FormSegment>
|
||||
<FormTextArea
|
||||
id="content"
|
||||
formValidationSchema={register('content')}
|
||||
placeholder="Comment"
|
||||
rows={2}
|
||||
error={!!errors.content?.message}
|
||||
disabled={formState.isSubmitting || isDeleting}
|
||||
/>
|
||||
</FormSegment>
|
||||
<div className="flex flex-row items-center justify-between">
|
||||
<div>
|
||||
<FormInfo>
|
||||
<FormLabel htmlFor="rating">Change your rating</FormLabel>
|
||||
<FormError>{errors.rating?.message}</FormError>
|
||||
</FormInfo>
|
||||
<Rating
|
||||
value={watch('rating')}
|
||||
onChange={(value) => {
|
||||
setValue('rating', value);
|
||||
}}
|
||||
>
|
||||
{Array.from({ length: 5 }).map((val, index) => (
|
||||
<Rating.Item
|
||||
name="rating-1"
|
||||
className="mask mask-star cursor-default"
|
||||
disabled={formState.isSubmitting || isDeleting}
|
||||
aria-disabled={formState.isSubmitting || isDeleting}
|
||||
key={index}
|
||||
/>
|
||||
))}
|
||||
</Rating>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<div className="w-4/12">
|
||||
<button
|
||||
type="submit"
|
||||
disabled={formState.isSubmitting || isDeleting}
|
||||
className="btn-ghost btn-sm btn w-full"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="w-4/12">
|
||||
<button
|
||||
type="button"
|
||||
className="btn-ghost btn-sm btn w-full"
|
||||
disabled={formState.isSubmitting || isDeleting}
|
||||
onClick={() => {
|
||||
setInEditMode(false);
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="w-4/12">
|
||||
<button
|
||||
type="button"
|
||||
className="btn-ghost btn-sm btn w-full"
|
||||
onClick={handleDelete}
|
||||
disabled={isDeleting || formState.isSubmitting}
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const CommentContentBody: FC<CommentCardDropdownProps> = ({
|
||||
comment,
|
||||
ref,
|
||||
mutate,
|
||||
inEditMode,
|
||||
setInEditMode,
|
||||
}) => {
|
||||
const { user } = useContext(UserContext);
|
||||
const timeDistance = useTimeDistance(new Date(comment.createdAt));
|
||||
|
||||
return (
|
||||
<div className="card-body animate-in fade-in-10" ref={ref}>
|
||||
<div className="flex flex-row justify-between">
|
||||
<div>
|
||||
<h3 className="font-semibold sm:text-2xl">
|
||||
<Link href={`/users/${comment.postedBy.id}`} className="link-hover link">
|
||||
{comment.postedBy.username}
|
||||
</Link>
|
||||
</h3>
|
||||
<h4 className="italic">
|
||||
posted{' '}
|
||||
<time
|
||||
className="tooltip tooltip-bottom"
|
||||
data-tip={format(new Date(comment.createdAt), 'MM/dd/yyyy')}
|
||||
>
|
||||
{timeDistance}
|
||||
</time>{' '}
|
||||
ago
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
{user && (
|
||||
<CommentCardDropdown
|
||||
comment={comment}
|
||||
mutate={mutate}
|
||||
inEditMode={inEditMode}
|
||||
setInEditMode={setInEditMode}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
<Rating value={comment.rating}>
|
||||
{Array.from({ length: 5 }).map((val, index) => (
|
||||
<Rating.Item
|
||||
name="rating-1"
|
||||
className="mask mask-star cursor-default"
|
||||
disabled
|
||||
aria-disabled
|
||||
key={index}
|
||||
/>
|
||||
))}
|
||||
</Rating>
|
||||
<p>{comment.content}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const CommentCardBody: FC<CommentCardProps> = ({ comment, mutate, ref }) => {
|
||||
const [inEditMode, setInEditMode] = useState(false);
|
||||
|
||||
return !inEditMode ? (
|
||||
<CommentContentBody
|
||||
comment={comment}
|
||||
inEditMode={inEditMode}
|
||||
mutate={mutate}
|
||||
ref={ref}
|
||||
setInEditMode={setInEditMode}
|
||||
/>
|
||||
<CommentContentBody comment={comment} ref={ref} setInEditMode={setInEditMode} />
|
||||
) : (
|
||||
<EditCommentBody
|
||||
comment={comment}
|
||||
inEditMode={inEditMode}
|
||||
mutate={mutate}
|
||||
ref={ref}
|
||||
setInEditMode={setInEditMode}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
47
src/components/BeerById/CommentCardDropdown.tsx
Normal file
47
src/components/BeerById/CommentCardDropdown.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import UserContext from '@/contexts/userContext';
|
||||
import { Dispatch, SetStateAction, FC, useContext } from 'react';
|
||||
import { FaEllipsisH } from 'react-icons/fa';
|
||||
import BeerCommentQueryResult from '@/services/BeerComment/schema/BeerCommentQueryResult';
|
||||
import { z } from 'zod';
|
||||
|
||||
interface CommentCardDropdownProps {
|
||||
comment: z.infer<typeof BeerCommentQueryResult>;
|
||||
setInEditMode: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const CommentCardDropdown: FC<CommentCardDropdownProps> = ({
|
||||
comment,
|
||||
setInEditMode,
|
||||
}) => {
|
||||
const { user } = useContext(UserContext);
|
||||
const isCommentOwner = user?.id === comment.postedBy.id;
|
||||
|
||||
return (
|
||||
<div className="dropdown-end dropdown">
|
||||
<label tabIndex={0} className="btn-ghost btn-sm btn m-1">
|
||||
<FaEllipsisH />
|
||||
</label>
|
||||
<ul
|
||||
tabIndex={0}
|
||||
className="dropdown-content menu rounded-box w-52 bg-base-100 p-2 shadow"
|
||||
>
|
||||
<li>
|
||||
{isCommentOwner ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setInEditMode(true);
|
||||
}}
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
) : (
|
||||
<button>Report</button>
|
||||
)}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CommentCardDropdown;
|
||||
67
src/components/BeerById/CommentContentBody.tsx
Normal file
67
src/components/BeerById/CommentContentBody.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import UserContext from '@/contexts/userContext';
|
||||
import useTimeDistance from '@/hooks/useTimeDistance';
|
||||
import { format } from 'date-fns';
|
||||
import { Dispatch, FC, SetStateAction, useContext } from 'react';
|
||||
import { Link, Rating } from 'react-daisyui';
|
||||
import BeerCommentQueryResult from '@/services/BeerComment/schema/BeerCommentQueryResult';
|
||||
import { useInView } from 'react-intersection-observer';
|
||||
import { z } from 'zod';
|
||||
import CommentCardDropdown from './CommentCardDropdown';
|
||||
|
||||
interface CommentContentBodyProps {
|
||||
comment: z.infer<typeof BeerCommentQueryResult>;
|
||||
ref: ReturnType<typeof useInView>['ref'] | undefined;
|
||||
setInEditMode: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const CommentContentBody: FC<CommentContentBodyProps> = ({
|
||||
comment,
|
||||
ref,
|
||||
setInEditMode,
|
||||
}) => {
|
||||
const { user } = useContext(UserContext);
|
||||
const timeDistance = useTimeDistance(new Date(comment.createdAt));
|
||||
|
||||
return (
|
||||
<div className="card-body animate-in fade-in-10" ref={ref}>
|
||||
<div className="flex flex-row justify-between">
|
||||
<div>
|
||||
<h3 className="font-semibold sm:text-2xl">
|
||||
<Link href={`/users/${comment.postedBy.id}`} className="link-hover link">
|
||||
{comment.postedBy.username}
|
||||
</Link>
|
||||
</h3>
|
||||
<h4 className="italic">
|
||||
posted{' '}
|
||||
<time
|
||||
className="tooltip tooltip-bottom"
|
||||
data-tip={format(new Date(comment.createdAt), 'MM/dd/yyyy')}
|
||||
>
|
||||
{timeDistance}
|
||||
</time>{' '}
|
||||
ago
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
{user && <CommentCardDropdown comment={comment} setInEditMode={setInEditMode} />}
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
<Rating value={comment.rating}>
|
||||
{Array.from({ length: 5 }).map((val, index) => (
|
||||
<Rating.Item
|
||||
name="rating-1"
|
||||
className="mask mask-star cursor-default"
|
||||
disabled
|
||||
aria-disabled
|
||||
key={index}
|
||||
/>
|
||||
))}
|
||||
</Rating>
|
||||
<p>{comment.content}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CommentContentBody;
|
||||
158
src/components/BeerById/EditCommentBody.tsx
Normal file
158
src/components/BeerById/EditCommentBody.tsx
Normal file
@@ -0,0 +1,158 @@
|
||||
import BeerCommentValidationSchema from '@/services/BeerComment/schema/CreateBeerCommentValidationSchema';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { FC, useState, useEffect, Dispatch, SetStateAction } from 'react';
|
||||
import { Rating } from 'react-daisyui';
|
||||
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
import useBeerPostComments from '@/hooks/useBeerPostComments';
|
||||
import BeerCommentQueryResult from '@/services/BeerComment/schema/BeerCommentQueryResult';
|
||||
import { useInView } from 'react-intersection-observer';
|
||||
import FormError from '../ui/forms/FormError';
|
||||
import FormInfo from '../ui/forms/FormInfo';
|
||||
import FormLabel from '../ui/forms/FormLabel';
|
||||
import FormSegment from '../ui/forms/FormSegment';
|
||||
import FormTextArea from '../ui/forms/FormTextArea';
|
||||
|
||||
interface CommentCardDropdownProps {
|
||||
comment: z.infer<typeof BeerCommentQueryResult>;
|
||||
setInEditMode: Dispatch<SetStateAction<boolean>>;
|
||||
ref: ReturnType<typeof useInView>['ref'] | undefined;
|
||||
mutate: ReturnType<typeof useBeerPostComments>['mutate'];
|
||||
}
|
||||
|
||||
const EditCommentBody: FC<CommentCardDropdownProps> = ({
|
||||
comment,
|
||||
setInEditMode,
|
||||
ref,
|
||||
mutate,
|
||||
}) => {
|
||||
const { register, handleSubmit, formState, setValue, watch } = useForm<
|
||||
z.infer<typeof BeerCommentValidationSchema>
|
||||
>({
|
||||
defaultValues: {
|
||||
content: comment.content,
|
||||
rating: comment.rating,
|
||||
},
|
||||
resolver: zodResolver(BeerCommentValidationSchema),
|
||||
});
|
||||
|
||||
const { errors } = formState;
|
||||
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
setIsDeleting(false);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleDelete = async () => {
|
||||
setIsDeleting(true);
|
||||
const response = await fetch(`/api/beer-comments/${comment.id}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to delete comment');
|
||||
}
|
||||
|
||||
await mutate();
|
||||
};
|
||||
|
||||
const onSubmit: SubmitHandler<z.infer<typeof BeerCommentValidationSchema>> = async (
|
||||
data,
|
||||
) => {
|
||||
const response = await fetch(`/api/beer-comments/${comment.id}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
content: data.content,
|
||||
rating: data.rating,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to update comment');
|
||||
}
|
||||
|
||||
await mutate();
|
||||
setInEditMode(false);
|
||||
};
|
||||
return (
|
||||
<div className="card-body animate-in fade-in-10" ref={ref}>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-3">
|
||||
<div>
|
||||
<FormInfo>
|
||||
<FormLabel htmlFor="content">Edit your comment</FormLabel>
|
||||
<FormError>{errors.content?.message}</FormError>
|
||||
</FormInfo>
|
||||
<FormSegment>
|
||||
<FormTextArea
|
||||
id="content"
|
||||
formValidationSchema={register('content')}
|
||||
placeholder="Comment"
|
||||
rows={2}
|
||||
error={!!errors.content?.message}
|
||||
disabled={formState.isSubmitting || isDeleting}
|
||||
/>
|
||||
</FormSegment>
|
||||
<div className="flex flex-row items-center justify-between">
|
||||
<div>
|
||||
<FormInfo>
|
||||
<FormLabel htmlFor="rating">Change your rating</FormLabel>
|
||||
<FormError>{errors.rating?.message}</FormError>
|
||||
</FormInfo>
|
||||
<Rating
|
||||
value={watch('rating')}
|
||||
onChange={(value) => {
|
||||
setValue('rating', value);
|
||||
}}
|
||||
>
|
||||
{Array.from({ length: 5 }).map((val, index) => (
|
||||
<Rating.Item
|
||||
name="rating-1"
|
||||
className="mask mask-star cursor-default"
|
||||
disabled={formState.isSubmitting || isDeleting}
|
||||
aria-disabled={formState.isSubmitting || isDeleting}
|
||||
key={index}
|
||||
/>
|
||||
))}
|
||||
</Rating>
|
||||
</div>
|
||||
<div className="btn-group btn-group-horizontal">
|
||||
<button
|
||||
type="button"
|
||||
className="btn-xs btn lg:btn-sm"
|
||||
disabled={formState.isSubmitting || isDeleting}
|
||||
onClick={() => {
|
||||
setInEditMode(false);
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={formState.isSubmitting || isDeleting}
|
||||
className="btn-xs btn lg:btn-sm"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="btn-xs btn lg:btn-sm"
|
||||
onClick={handleDelete}
|
||||
disabled={isDeleting || formState.isSubmitting}
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditCommentBody;
|
||||
@@ -86,28 +86,34 @@ const Navbar = () => {
|
||||
<span className="cursor-pointer text-lg font-bold">The Biergarten App</span>
|
||||
</Link>
|
||||
</div>
|
||||
<div>
|
||||
<div>{isDesktopView ? <DesktopLinks /> : <MobileLinks />}</div>{' '}
|
||||
{theme === 'light' ? (
|
||||
<button
|
||||
className="btn-ghost btn-md btn-circle btn"
|
||||
data-set-theme="dark"
|
||||
data-act-class="ACTIVECLASS"
|
||||
onClick={() => setTheme('dark')}
|
||||
>
|
||||
<MdLightMode className="text-xl" />
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
className="btn-ghost btn-md btn-circle btn"
|
||||
data-set-theme="light"
|
||||
data-act-class="ACTIVECLASS"
|
||||
onClick={() => setTheme('light')}
|
||||
>
|
||||
<MdDarkMode className="text-xl" />
|
||||
</button>
|
||||
)}
|
||||
|
||||
<div
|
||||
className="tooltip tooltip-left"
|
||||
data-tip={theme === 'light' ? 'Switch to dark mode' : 'Switch to light mode'}
|
||||
>
|
||||
<div>
|
||||
{theme === 'light' ? (
|
||||
<button
|
||||
className="btn-ghost btn-md btn-circle btn"
|
||||
data-set-theme="dark"
|
||||
data-act-class="ACTIVECLASS"
|
||||
onClick={() => setTheme('dark')}
|
||||
>
|
||||
<MdLightMode className="text-xl" />
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
className="btn-ghost btn-md btn-circle btn"
|
||||
data-set-theme="light"
|
||||
data-act-class="ACTIVECLASS"
|
||||
onClick={() => setTheme('light')}
|
||||
>
|
||||
<MdDarkMode className="text-xl" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div>{isDesktopView ? <DesktopLinks /> : <MobileLinks />}</div>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,8 +8,8 @@ interface ErrorAlertProps {
|
||||
|
||||
const ErrorAlert: FC<ErrorAlertProps> = ({ error, setError }) => {
|
||||
return (
|
||||
<div className="alert alert-error shadow-lg">
|
||||
<div>
|
||||
<div className="alert alert-error flex-row shadow-lg">
|
||||
<div className="space-x-1">
|
||||
<FiAlertTriangle className="h-6 w-6" />
|
||||
<span>{error}</span>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@ interface FormLabelProps {
|
||||
*/
|
||||
const FormLabel: FunctionComponent<FormLabelProps> = ({ htmlFor, children }) => (
|
||||
<label
|
||||
className="my-1 block text-sm font-extrabold uppercase tracking-wide sm:text-xs"
|
||||
className="my-1 block text-xs font-extrabold uppercase tracking-wide lg:text-sm"
|
||||
htmlFor={htmlFor}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -19,7 +19,7 @@ const FormPageLayout: FC<FormPageLayoutProps> = ({
|
||||
backLinkText,
|
||||
}) => {
|
||||
return (
|
||||
<div className="align-center my-20 flex flex-col items-center justify-center">
|
||||
<div className="my-20 flex flex-col items-center justify-center">
|
||||
<div className="w-10/12 lg:w-8/12 2xl:w-6/12">
|
||||
<div className="tooltip tooltip-right" data-tip={backLinkText}>
|
||||
<Link href={backLink} className="btn-ghost btn-sm btn p-0">
|
||||
@@ -28,7 +28,7 @@ const FormPageLayout: FC<FormPageLayoutProps> = ({
|
||||
</div>
|
||||
<div className="flex flex-col items-center space-y-1">
|
||||
{headingIcon({ className: 'text-4xl' })}{' '}
|
||||
<h1 className="text-3xl font-bold">{headingText}</h1>
|
||||
<h1 className="text-center text-3xl font-bold">{headingText}</h1>
|
||||
</div>
|
||||
<div className="mt-3">{FormComponent}</div>
|
||||
</div>
|
||||
|
||||
@@ -40,7 +40,7 @@ const FormTextArea: FunctionComponent<FormTextAreaProps> = ({
|
||||
<textarea
|
||||
id={id}
|
||||
placeholder={placeholder}
|
||||
className={`textarea-bordered textarea m-0 w-full resize-none rounded-lg border border-solid bg-clip-padding transition ease-in-out ${
|
||||
className={`text-md textarea-bordered textarea m-0 w-full resize-none rounded-lg border border-solid transition ease-in-out ${
|
||||
error ? 'textarea-error' : ''
|
||||
}`}
|
||||
{...formValidationSchema}
|
||||
|
||||
@@ -46,7 +46,7 @@ const FormTextInput: FunctionComponent<FormInputProps> = ({
|
||||
id={id}
|
||||
type={type}
|
||||
placeholder={placeholder}
|
||||
className={`input-bordered input w-full rounded-lg transition ease-in-out ${
|
||||
className={`input-bordered input w-full appearance-none rounded-lg transition ease-in-out ${
|
||||
error ? 'input-error' : ''
|
||||
}`}
|
||||
{...formValidationSchema}
|
||||
|
||||
Reference in New Issue
Block a user