Skip to content

Commit

Permalink
Merge pull request #107 from ciampo/feat/ratings
Browse files Browse the repository at this point in the history
GH-54 re-enable blog post ratings, but with a different Sanity schema…
  • Loading branch information
ciampo authored Jul 31, 2020
2 parents a3d2cc2 + 87d689b commit c513c69
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 92 deletions.
58 changes: 29 additions & 29 deletions components/blog-post/Recipe.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import React, { useCallback } from 'react';
import { useRouter } from 'next/router';
// import { useLocalStorage } from 'react-use';
import { useLocalStorage } from 'react-use';

// import RatingForm from './RatingForm';
// import { usePostReviewsState } from './blog-post-reviews-context';
// import { StarEmptyIcon, StarHalfIcon, StarFullIcon } from '../icons';
import RatingForm from './RatingForm';
import { usePostReviewsState } from './blog-post-reviews-context';
import { StarEmptyIcon, StarHalfIcon, StarFullIcon } from '../icons';
import SimplePortableText from '../portable-text/SimplePortableText';
import { ArticleContentContainer } from '../layouts/Containers';
import { stringifyRecipeIngredient, stringifyRecipeQuantity, joinUrl } from '../../scripts/utils';
Expand All @@ -25,41 +25,41 @@ import { AllSharingButtons } from '../sharing/sharing-links';

import { socialShareLabel } from '../../data/siteMiscContent.json';

// type ReviewsRegistry = {
// [key: string]: number;
// };
// const RECIPE_REVIEW_LS_KEY = 'oa-reviews';
type ReviewsRegistry = {
[key: string]: number;
};
const RECIPE_REVIEW_LS_KEY = 'oa-reviews';

const RecipeSectionTitle: React.FC<{ text: string }> = ({ text }) => (
<h3 className="type-heading-2 text-center">{text}</h3>
);

// const REVIEW_THANK_YOU_MESSAGE = 'Thank you for rating this recipe!';
const REVIEW_THANK_YOU_MESSAGE = 'Thank you for rating this recipe!';

type RecipeProps = {
recipe: SanityRecipe;
className?: string;
};
const Recipe: React.FC<RecipeProps> = ({ recipe, className }) => {
const { asPath } = useRouter();
// const reviewsState = usePostReviewsState();
const reviewsState = usePostReviewsState();

// const [postReviews, setpostReviews] = useLocalStorage<ReviewsRegistry>(RECIPE_REVIEW_LS_KEY, {});
const [postReviews, setPostReviews] = useLocalStorage<ReviewsRegistry>(RECIPE_REVIEW_LS_KEY, {});

// const localReviewExists =
// reviewsState?.data?.documentId && postReviews[reviewsState.data.documentId];
const localReviewExists =
reviewsState?.data?.documentId && postReviews[reviewsState.data.documentId];

// const addReviewToLocalStorage = useCallback(
// (rating: number) => {
// if (reviewsState?.data?.documentId) {
// setpostReviews({
// ...postReviews,
// [reviewsState.data.documentId]: rating,
// });
// }
// },
// [reviewsState?.data?.documentId, postReviews, setpostReviews]
// );
const addReviewToLocalStorage = useCallback(
(rating: number) => {
if (reviewsState?.data?.documentId) {
setPostReviews({
...postReviews,
[reviewsState.data.documentId]: rating,
});
}
},
[reviewsState?.data?.documentId, postReviews, setPostReviews]
);

return (
<article
Expand All @@ -80,7 +80,7 @@ const Recipe: React.FC<RecipeProps> = ({ recipe, className }) => {
<h2 className="type-display-2 text-center mt-4 xl:mt-6">{recipe.title}</h2>

{/* Rating — read only */}
{/* <p className="flex flex-col items-center text-olive-darker space-y-1">
<p className="flex flex-col items-center text-olive-darker space-y-1">
<span
aria-label={
reviewsState.data.reviewCount > 0
Expand All @@ -105,7 +105,7 @@ const Recipe: React.FC<RecipeProps> = ({ recipe, className }) => {
? `${reviewsState.data.reviewCount} reviews`
: 'No reviews yet'}
</span>
</p> */}
</p>
</header>

{/* Sharing */}
Expand Down Expand Up @@ -241,7 +241,7 @@ const Recipe: React.FC<RecipeProps> = ({ recipe, className }) => {
</ArticleContentContainer>

{/* Interactive rating */}
{/* <aside className="bg-olive-darker text-white py-10 sm:py-12 md:py-16 xl:py-20">
<aside className="bg-olive-darker text-white py-10 sm:py-12 md:py-16 xl:py-20">
<ArticleContentContainer>
{localReviewExists ? (
<p className="type-heading-4 text-center">{REVIEW_THANK_YOU_MESSAGE}</p>
Expand All @@ -253,7 +253,7 @@ const Recipe: React.FC<RecipeProps> = ({ recipe, className }) => {
)}
<noscript>Please enable JavaScript to submit a review for this recipe.</noscript>
</ArticleContentContainer>
</aside> */}
</aside>
</article>
);
};
Expand Down
7 changes: 5 additions & 2 deletions components/blog-post/sanity-browser-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ const client = sanityClient({
ignoreBrowserTokenWarning: true,
});

export const getPostReviews = async (postId: string): Promise<{ reviews: number[] }> =>
await client.fetch(`*[_id == "${postId}"] {"reviews": coalesce(reviews[], [])}[0]`);
type BlogPostRating = {
rating: number;
};
export const getPostReviews = async (postId: string): Promise<BlogPostRating[]> =>
await client.fetch(`*[_type == "blogPostRating" && post._ref == "${postId}" ]`);
24 changes: 15 additions & 9 deletions functions/submission-created.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,12 @@ exports.handler = async (event) => {
};
}

if (!sanityDocumentId) {
console.error('Invalid document ID');
if (!sanityDocumentId || /^draft/.test(sanityDocumentId)) {
const msg = `Invalid document ID: ${sanityDocumentId}`;
console.error(msg);
return {
statusCode: 422,
body: 'Invalid documentID',
body: msg,
};
}

Expand All @@ -190,12 +191,17 @@ exports.handler = async (event) => {
});

try {
const result = await client
.patch(sanityDocumentId)
.setIfMissing({ reviews: [] })
.append('reviews', [parseInt(ratingAsString, 10)])
.commit();
console.log('Reviews updated', result);
const doc = {
_type: 'blogPostRating',
post: {
_ref: sanityDocumentId,
_type: 'reference',
},
rating: parseInt(ratingAsString, 10),
};

const result = await client.create(doc);
console.log('New document created', result._id);

await fetch(SLACK_WEBHOOK_URL, {
headers: {
Expand Down
4 changes: 2 additions & 2 deletions pages-tests/blogpost.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const blogPostData = testRecipeData as SanityBlogPostFull;

jest.mock('../components/blog-post/sanity-browser-client', () => {
return {
getPostReviews: (): { reviews: number[] } => {
return { reviews: [1, 5, 3] };
getPostReviews: (): { rating: number }[] => {
return [{ rating: 1 }, { rating: 5 }, { rating: 3 }];
},
};
});
Expand Down
6 changes: 2 additions & 4 deletions pages-tests/data/test-category.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@
"categoryId": "test-category",
"postId": "blog-post-slug"
}
},
"reviews": []
}
}
],
"featuredBlogPosts": [
Expand Down Expand Up @@ -214,8 +213,7 @@
"categoryId": "test-category",
"postId": "blog-post-slug"
}
},
"reviews": []
}
}
],
"name": "Test category",
Expand Down
62 changes: 31 additions & 31 deletions pages/[categoryId]/[postId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import { useNavVariantDispatch } from '../../components/nav/nav-variant-context'
import {
PostReviewsProvider,
usePostReviewsState,
// usePostReviewsDispatch,
usePostReviewsDispatch,
} from '../../components/blog-post/blog-post-reviews-context';
// import { getPostReviews } from '../../components/blog-post/sanity-browser-client';
import { getPostReviews } from '../../components/blog-post/sanity-browser-client';

import { joinUrl, postDateToHumanString } from '../../scripts/utils';

Expand Down Expand Up @@ -52,7 +52,7 @@ type PageBlogPostProps = {
};
const BlogPostWrapped: React.FC<PageBlogPostProps> = ({ blogPostData, path, structuredData }) => {
const postReviewsState = usePostReviewsState();
// const postReviewsDispatch = usePostReviewsDispatch();
const postReviewsDispatch = usePostReviewsDispatch();
const setVariant = useNavVariantDispatch();
useEffect(() => {
setVariant('transparent');
Expand All @@ -73,34 +73,34 @@ const BlogPostWrapped: React.FC<PageBlogPostProps> = ({ blogPostData, path, stru
};
}

// useEffect(() => {
// const fetchData = async (): Promise<void> => {
// postReviewsDispatch({ type: 'FETCH_INIT' });

// try {
// const { reviews } = await getPostReviews(blogPostData._id);

// let ratingValue = -1;
// if (reviews.length) {
// // average
// ratingValue = reviews.reduce((acc, curr) => acc + curr, 0) / reviews.length;
// }

// postReviewsDispatch({
// type: 'FETCH_SUCCESS',
// payload: {
// ratingValue,
// reviewCount: reviews.length,
// documentId: blogPostData._id,
// },
// });
// } catch (error) {
// postReviewsDispatch({ type: 'FETCH_ERROR' });
// }
// };

// fetchData();
// }, [postReviewsDispatch, blogPostData._id]);
useEffect(() => {
const fetchData = async (): Promise<void> => {
postReviewsDispatch({ type: 'FETCH_INIT' });

try {
const reviews = await getPostReviews(blogPostData._id);

let ratingValue = -1;
if (reviews.length) {
// average
ratingValue = reviews.reduce((acc, curr) => acc + curr.rating, 0) / reviews.length;
}

postReviewsDispatch({
type: 'FETCH_SUCCESS',
payload: {
ratingValue,
reviewCount: reviews.length,
documentId: blogPostData._id,
},
});
} catch (error) {
postReviewsDispatch({ type: 'FETCH_ERROR' });
}
};

fetchData();
}, [postReviewsDispatch, blogPostData._id]);

return (
<>
Expand Down
1 change: 0 additions & 1 deletion sanity/blogPost.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const allBlogPostsQuery = /* groq */ `*[_type == "${blogPostType}"] {
"seoTitle": ${pageBlogPostQuery}[0].seoTitle,
"seoDescription": ${pageBlogPostQuery}[0].seoDescription,
"seoImage": seoImage.asset->url,
"reviews": coalesce(reviews[], []),
}`;

function replaceBlogPostContent(blogPostItem, content) {
Expand Down
1 change: 0 additions & 1 deletion sanity/projections.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ const blogPostPreviewProjection = /* groq */ `{
"tags":tags[]->${tagPreviewProjection},
datePublished,
previewImage->${accessibleImageProjection},
"reviews": coalesce(reviews[], []),
}`;

module.exports = {
Expand Down
24 changes: 12 additions & 12 deletions scripts/structured-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export function generateRecipeStructuredData({
prepTime: `PT${recipeData.preparationTime}M`,
cookTime: `PT${recipeData.cookingTime}M`,
totalTime: `PT${recipeData.preparationTime + recipeData.cookingTime}M`,
recipeYield: `${recipeData.servings.quantity} ${recipeData.servings.unit}`,
recipeYield: recipeData.servings.quantity,
recipeCategory: recipeData.category,
recipeCuisine: recipeData.cuisine,
nutrition: {
Expand All @@ -182,17 +182,17 @@ export function generateRecipeStructuredData({
// Missing: video
};

if (blogPostData.reviews.length) {
toReturn.aggregateRating = {
'@type': 'AggregateRating',
reviewCount: blogPostData.reviews.length,
ratingValue:
Math.round(
(100 * blogPostData.reviews.reduce((acc, curr) => acc + curr, 0)) /
blogPostData.reviews.length
) / 100,
};
}
// if (blogPostData.reviews.length) {
// toReturn.aggregateRating = {
// '@type': 'AggregateRating',
// reviewCount: blogPostData.reviews.length,
// ratingValue:
// Math.round(
// (100 * blogPostData.reviews.reduce((acc, curr) => acc + curr, 0)) /
// blogPostData.reviews.length
// ) / 100,
// };
// }

return toReturn;
}
Expand Down
7 changes: 7 additions & 0 deletions styles/base.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
/* purgecss start ignore */
@media screen and (prefers-reduced-motion: no-preference) {
html,
body {
scroll-behavior: smooth;
}
}

a,
button,
input,
Expand Down
1 change: 0 additions & 1 deletion typings/sanity-blog-post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export type SanityBlogPostBase = {
category: SanityCategoryPreview;
tags: SanityTag[];
datePublished: string;
reviews: number[];
};

export type SanityBlogPostPreview = SanityBlogPostBase & {
Expand Down

0 comments on commit c513c69

Please sign in to comment.