Refactoring of components and styling of full recipe page.

This commit is contained in:
Jesse Brault 2024-08-01 15:38:20 -05:00
parent a983d49f22
commit a3443ce274
12 changed files with 123 additions and 47 deletions

View File

@ -40,7 +40,8 @@ const getRecipe = async ({
ownerUsername,
starCount,
viewerCount,
mainImage: rawMainImage
mainImage: rawMainImage,
isPublic
} = (await response.json()) as RawFullRecipeView
return {
id,
@ -53,7 +54,8 @@ const getRecipe = async ({
ownerUsername,
starCount,
viewerCount,
mainImage: toImageView(rawMainImage)
mainImage: toImageView(rawMainImage),
isPublic
}
} else if (response.status === 404) {
throw notFound()

View File

@ -12,6 +12,7 @@ export interface RawFullRecipeView {
starCount: number
viewerCount: number
mainImage: RawImageView
isPublic: boolean
}
interface FullRecipeView {
@ -26,6 +27,7 @@ interface FullRecipeView {
starCount: number
viewerCount: number
mainImage: ImageView
isPublic: boolean
}
export default FullRecipeView

View File

@ -1,6 +1,8 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import classes from './recipe-card.module.css'
import { Link } from '@tanstack/react-router'
import RecipeVisibilityIcon from '../recipe-visibility-icon/RecipeVisibilityIcon'
import StarCount from '../star-count/StarCount'
import UserIconAndName from '../user-icon-and-name/UserIconAndName'
import classes from './recipe-card.module.css'
export interface RecipeCardProps {
title: string
@ -49,28 +51,11 @@ const RecipeCard = ({
>
<h1 className={classes.title}>{title}</h1>
</Link>
<span className={classes.starInfo}>
<FontAwesomeIcon
icon="star"
className={classes.star}
size="sm"
/>
{starCount}
</span>
<StarCount count={starCount} />
</div>
<div className={classes.infoRow}>
<span className={classes.userInfo}>
<FontAwesomeIcon
icon="user"
className={classes.userIcon}
/>
{ownerUsername}
</span>
{isPublic ? (
<FontAwesomeIcon icon="globe" size="sm" />
) : (
<FontAwesomeIcon icon="lock" size="sm" />
)}
<UserIconAndName username={ownerUsername} />
<RecipeVisibilityIcon isPublic={isPublic} />
</div>
</div>
</article>

View File

@ -23,22 +23,3 @@
margin-block: 0;
font-size: 18px;
}
.star-info {
display: flex;
column-gap: 5px;
align-items: center;
}
.star {
color: var(--primary-yellow);
}
.user-info {
display: flex;
column-gap: 5px;
}
.user-icon {
color: var(--primary-red);
}

View File

@ -0,0 +1,23 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import classes from './recipe-visibility-icon.module.css'
export interface RecipeVisibilityIconProps {
isPublic: boolean
}
const RecipeVisibilityIcon = ({ isPublic }: RecipeVisibilityIconProps) =>
isPublic ? (
<FontAwesomeIcon
icon="globe"
className={classes.recipeVisibilityIcon}
size="sm"
/>
) : (
<FontAwesomeIcon
icon="lock"
className={classes.recipeVisibilityIcon}
size="sm"
/>
)
export default RecipeVisibilityIcon

View File

@ -0,0 +1,3 @@
.recipe-visibility-icon {
color: var(--primary-red);
}

View File

@ -0,0 +1,15 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import classes from './star-count.module.css'
export interface StarCountProps {
count: number
}
const StarCount = ({ count }: StarCountProps) => (
<span className={classes.starInfo}>
<FontAwesomeIcon icon="star" className={classes.star} size="sm" />
{count}
</span>
)
export default StarCount

View File

@ -0,0 +1,9 @@
.star-info {
display: flex;
column-gap: 5px;
align-items: center;
}
.star {
color: var(--primary-yellow);
}

View File

@ -0,0 +1,15 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import classes from './user-icon-and-name.module.css'
export interface UserIconAndNameProps {
username: string
}
const UserIconAndName = ({ username }: UserIconAndNameProps) => (
<span className={classes.userInfo}>
<FontAwesomeIcon icon="user" className={classes.userIcon} />
{username}
</span>
)
export default UserIconAndName

View File

@ -0,0 +1,8 @@
.user-info {
display: flex;
column-gap: 5px;
}
.user-icon {
color: var(--primary-red);
}

View File

@ -1,4 +1,8 @@
import FullRecipeView from '../../api/types/FullRecipeView'
import RecipeVisibilityIcon from '../../components/recipe-visibility-icon/RecipeVisibilityIcon'
import StarCount from '../../components/star-count/StarCount'
import UserIconAndName from '../../components/user-icon-and-name/UserIconAndName'
import classes from './recipe.module.css'
export interface RecipeProps {
recipe: FullRecipeView
@ -6,10 +10,20 @@ export interface RecipeProps {
const Recipe = ({ recipe }: RecipeProps) => {
return (
<article>
<h1>{recipe.title}</h1>
<div dangerouslySetInnerHTML={{ __html: recipe.text }} />
</article>
<div className={classes.fullRecipeContainer}>
<article className={classes.fullRecipe}>
<img src={recipe.mainImage.url} className={classes.mainImage} />
<div className={classes.infoRow}>
<h1>{recipe.title}</h1>
<StarCount count={recipe.starCount} />
</div>
<div className={classes.infoRow}>
<UserIconAndName username={recipe.ownerUsername} />
<RecipeVisibilityIcon isPublic={recipe.isPublic} />
</div>
<div dangerouslySetInnerHTML={{ __html: recipe.text }} />
</article>
</div>
)
}

View File

@ -0,0 +1,19 @@
.full-recipe-container {
display: flex;
flex-direction: column;
align-items: center;
max-width: 100%;
}
.full-recipe {
max-width: 600px;
}
.full-recipe .main-image {
width: 100%;
}
.full-recipe .info-row {
display: flex;
justify-content: space-between;
}