Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prod release #2153

Merged
merged 10 commits into from
May 7, 2024
204 changes: 106 additions & 98 deletions next-sitemap.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-console */
/* eslint-disable max-lines */
/* eslint-disable jsdoc/require-returns */
/* eslint-disable import/no-extraneous-dependencies */
Expand All @@ -12,6 +13,8 @@ const { locales } = require('./i18n.json');

const isProduction = process.env.NEXT_PUBLIC_VERCEL_ENV === 'production';
const isDevelopment = process.env.NEXT_PUBLIC_VERCEL_ENV === 'development';
const shouldGenerateAdditionalPaths =
process.env.NEXT_PUBLIC_GENERATE_SITEMAP_ADDITIONAL_PATHS === 'true';

const BASE_PATH =
`${isDevelopment ? 'http' : 'https'}://${process.env.NEXT_PUBLIC_VERCEL_URL}` ||
Expand Down Expand Up @@ -96,114 +99,119 @@ module.exports = {
alternateRefs: config.alternateRefs ?? [],
};
},
additionalPaths: async (config) => {
const result = [];
let tafsirSlugs = [];
let reciterIds = [];
await getAvailableTafsirs().then((response) => {
tafsirSlugs = response.tafsirs.map((tafsir) => tafsir.slug);
});
await getAvailableReciters().then((response) => {
reciterIds = response.reciters.map((reciter) => reciter.id);
});
chapters.forEach((chapterId) => {
// 1. add the chapter slugs in English along with the localized slugs in every locale
const englishChapterSlug = englishChaptersData[chapterId].slug;
result.push({
loc: `/${englishChapterSlug}`,
alternateRefs: getAlternateRefs(chapterId),
});
// 2. add slugged /surah/[chapterSlug]/info in English along with the localized slugs in every locale
result.push({
loc: `/surah/${englishChapterSlug}/info`,
alternateRefs: getAlternateRefs(chapterId, true, 'surah', 'info'),
});

// 3. /reciters/[reciterId]/[chapterSlug]
reciterIds.forEach((reciterId) => {
const location = `/reciters/${reciterId}/${englishChapterSlug}`;
result.push({
loc: location,
alternateRefs: getAlternateRefs(chapterId, false, '', location),
additionalPaths: shouldGenerateAdditionalPaths
? async (config) => {
const result = [];
let tafsirSlugs = [];
let reciterIds = [];
await getAvailableTafsirs().then((response) => {
tafsirSlugs = response.tafsirs.map((tafsir) => tafsir.slug);
});
});

// 4. generate the verses for each of the chapters in each locale as well
range(englishChaptersData[chapterId].versesCount).forEach((verseId) => {
const verseNumber = verseId + 1;
const verseIdValue = verseNumber;
const verseKey = `${chapterId}:${verseIdValue}`;
const isAyatulKursi = chapterId === 2 && verseNumber === 255;
if (isAyatulKursi) {
// instead of /al-baqarah/255, we push /ayatul-kursi
await getAvailableReciters().then((response) => {
reciterIds = response.reciters.map((reciter) => reciter.id);
});
chapters.forEach((chapterId) => {
// 1. add the chapter slugs in English along with the localized slugs in every locale
const englishChapterSlug = englishChaptersData[chapterId].slug;
result.push({
loc: `/ayatul-kursi`,
alternateRefs: getAlternateRefs(null, false, '', 'ayatul-kursi'),
loc: `/${englishChapterSlug}`,
alternateRefs: getAlternateRefs(chapterId),
});
} else {
// 2. add slugged /surah/[chapterSlug]/info in English along with the localized slugs in every locale
result.push({
loc: `/${englishChapterSlug}/${verseIdValue}`,
alternateRefs: getAlternateRefs(chapterId, true, '', verseIdValue),
loc: `/surah/${englishChapterSlug}/info`,
alternateRefs: getAlternateRefs(chapterId, true, 'surah', 'info'),
});

// 3. /reciters/[reciterId]/[chapterSlug]
reciterIds.forEach((reciterId) => {
const location = `/reciters/${reciterId}/${englishChapterSlug}`;
result.push({
loc: location,
alternateRefs: getAlternateRefs(chapterId, false, '', location),
});
});
}
// 5. add /[chapterId]/[verseId]/tafsirs route
result.push({
loc: `/${englishChapterSlug}/${verseIdValue}/tafsirs`,
alternateRefs: getAlternateRefs(chapterId, true, '', `${verseIdValue}/tafsirs`),

// 4. generate the verses for each of the chapters in each locale as well
range(englishChaptersData[chapterId].versesCount).forEach((verseId) => {
const verseNumber = verseId + 1;
const verseIdValue = verseNumber;
const verseKey = `${chapterId}:${verseIdValue}`;
const isAyatulKursi = chapterId === 2 && verseNumber === 255;
if (isAyatulKursi) {
// instead of /al-baqarah/255, we push /ayatul-kursi
result.push({
loc: `/ayatul-kursi`,
alternateRefs: getAlternateRefs(null, false, '', 'ayatul-kursi'),
});
} else {
result.push({
loc: `/${englishChapterSlug}/${verseIdValue}`,
alternateRefs: getAlternateRefs(chapterId, true, '', verseIdValue),
});
}
// 5. add /[chapterId]/[verseId]/tafsirs route
result.push({
loc: `/${englishChapterSlug}/${verseIdValue}/tafsirs`,
alternateRefs: getAlternateRefs(chapterId, true, '', `${verseIdValue}/tafsirs`),
});
// 6. /[verseKey]/tafsirs/[tafsirSlug]
tafsirSlugs.forEach((tafsirSlug) => {
const location = `${verseKey}/tafsirs/${tafsirSlug}`;
result.push({
loc: location,
alternateRefs: getAlternateRefs(chapterId, false, '', location),
});
});
// 7. /[verseKey]/reflections
const reflectionsLocation = `${verseKey}/reflections`;
result.push({
loc: reflectionsLocation,
alternateRefs: getAlternateRefs(chapterId, false, '', reflectionsLocation),
});
});
});
// 7. /juz/[juzId]
range(1, 31).forEach(async (juzId) => {
result.push(await config.transform(config, `/juz/${juzId}`));
});
// 8. /hizb/[hizbId]
range(1, 61).forEach(async (hizbId) => {
result.push(await config.transform(config, `/hizb/${hizbId}`));
});
// 6. /[verseKey]/tafsirs/[tafsirSlug]
tafsirSlugs.forEach((tafsirSlug) => {
const location = `${verseKey}/tafsirs/${tafsirSlug}`;
// 9. /rub/[rubId]
range(1, 241).forEach(async (rubId) => {
result.push(await config.transform(config, `/rub/${rubId}`));
});
// 10. /page/[pageId]
range(1, 605).forEach(async (pageId) => {
result.push(await config.transform(config, `/page/${pageId}`));
});
// 11. /reciters/[reciterId]
reciterIds.forEach((reciterId) => {
const location = `/reciters/${reciterId}`;
result.push({
loc: location,
alternateRefs: getAlternateRefs(chapterId, false, '', location),
alternateRefs: getAlternateRefs('', false, '', location),
});
});
// 7. /[verseKey]/reflections
const reflectionsLocation = `${verseKey}/reflections`;
result.push({
loc: reflectionsLocation,
alternateRefs: getAlternateRefs(chapterId, false, '', reflectionsLocation),
});
});
});
// 7. /juz/[juzId]
range(1, 31).forEach(async (juzId) => {
result.push(await config.transform(config, `/juz/${juzId}`));
});
// 8. /hizb/[hizbId]
range(1, 61).forEach(async (hizbId) => {
result.push(await config.transform(config, `/hizb/${hizbId}`));
});
// 9. /rub/[rubId]
range(1, 241).forEach(async (rubId) => {
result.push(await config.transform(config, `/rub/${rubId}`));
});
// 10. /page/[pageId]
range(1, 605).forEach(async (pageId) => {
result.push(await config.transform(config, `/page/${pageId}`));
});
// 11. /reciters/[reciterId]
reciterIds.forEach((reciterId) => {
const location = `/reciters/${reciterId}`;
result.push({
loc: location,
alternateRefs: getAlternateRefs('', false, '', location),
});
});

// 12. /learning-plans/[learningPlanSlug]
const learningPlans = await getAvailableCourses();
// TODO: handle pagination in the future when we have more than 10 learning plans
learningPlans.data.forEach((learningPlan) => {
const location = `/learning-plans/${learningPlan.slug}`;
// TODO: handle per language learning plans e.g. Arabic learning plan should only show under /ar/[learning-plan-slug]
result.push({
loc: location,
alternateRefs: getAlternateRefs('', false, '', location),
});
});
// 12. /learning-plans/[learningPlanSlug]
const learningPlans = await getAvailableCourses();
// TODO: handle pagination in the future when we have more than 10 learning plans
learningPlans.data.forEach((learningPlan) => {
const location = `/learning-plans/${learningPlan.slug}`;
// TODO: handle per language learning plans e.g. Arabic learning plan should only show under /ar/[learning-plan-slug]
result.push({
loc: location,
alternateRefs: getAlternateRefs('', false, '', location),
});
});

return result;
},
return result;
}
: async () => {
console.log('Skipping additional paths generation...');
return Promise.resolve([]);
},
};
5 changes: 4 additions & 1 deletion src/components/Banner/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useSelector } from 'react-redux';

import styles from './Banner.module.scss';

// import MoonIllustrationSVG from '@/public/images/moon-illustration.svg';
import MoonIllustrationSVG from '@/public/images/moon-illustration.svg';
import { selectIsBannerVisible } from '@/redux/slices/banner';

type BannerProps = {
Expand All @@ -21,6 +21,9 @@ const Banner = ({ text, ctaButton }: BannerProps) => {
})}
>
<div className={styles.description}>
<div className={styles.illustrationContainer}>
<MoonIllustrationSVG />
</div>
<div className={styles.text}>{text}</div>
</div>
{ctaButton && <div className={styles.ctaContainer}>{ctaButton}</div>}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Course/Buttons/NavbarButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Button, { ButtonSize, ButtonType } from '@/dls/Button/Button';
import { logButtonClick } from '@/utils/eventLogger';
import { getCourseNavigationUrl } from '@/utils/navigation';

const LEARNING_PLAN_SLUG = 'avoiding-the-post-ramadan-slump';
const LEARNING_PLAN_SLUG = 'preparing-our-hearts-for-ramadan';

const NavbarButton = () => {
const { t } = useTranslation('common');
Expand Down
5 changes: 0 additions & 5 deletions src/components/Navbar/Navbar.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,4 @@
.hiddenNav {
// https://ptgamr.github.io/2014-09-13-translate3d-vs-translate-performance/
transform: translate3d(0, calc(-1 * var(--navbar-container-height)), 0);

// TODO: remove this when banner is removed
@include breakpoints.smallerThanTablet {
transform: translate3d(0, calc(-1 * (var(--navbar-container-height) + var(--banner-height))), 0);
}
}
5 changes: 0 additions & 5 deletions src/components/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import React from 'react';

import classNames from 'classnames';
import useTranslation from 'next-translate/useTranslation';
import { useSelector, shallowEqual } from 'react-redux';

import styles from './Navbar.module.scss';
import NavbarBody from './NavbarBody';

import Banner from '@/components/Banner/Banner';
import LearningPlanButton from '@/components/Course/Buttons/NavbarButton';
import { useOnboarding } from '@/components/Onboarding/OnboardingProvider';
import { selectNavbar } from '@/redux/slices/navbar';

const Navbar = () => {
const { t } = useTranslation('common');
const { isActive } = useOnboarding();
const { isVisible: isNavbarVisible } = useSelector(selectNavbar, shallowEqual);
const showNavbar = isNavbarVisible || isActive;
Expand All @@ -22,7 +18,6 @@ const Navbar = () => {
<>
<div className={styles.emptySpacePlaceholder} />
<nav className={classNames(styles.container, { [styles.hiddenNav]: !showNavbar })}>
<Banner text={t('prepare-hearts.title')} ctaButton={<LearningPlanButton />} />
<NavbarBody />
</nav>
</>
Expand Down
4 changes: 3 additions & 1 deletion src/components/Onboarding/OnboardingProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* eslint-disable max-lines */
import React, { useMemo, useCallback, useState } from 'react';

import dynamic from 'next/dynamic';
import useTranslation from 'next-translate/useTranslation';
import Joyride, { ACTIONS, Callback, EVENTS, STATUS, StoreHelpers } from 'react-joyride';
import { ACTIONS, Callback, EVENTS, STATUS, StoreHelpers } from 'react-joyride';
import { useSelector, useDispatch } from 'react-redux';

// eslint-disable-next-line import/no-cycle
Expand All @@ -14,6 +15,7 @@ import { selectOnboardingActiveStep, setActiveStepIndex } from '@/redux/slices/o
import OnboardingGroup from '@/types/OnboardingGroup';
import { isLoggedIn } from '@/utils/auth/login';

const Joyride = dynamic(() => import('react-joyride'), { ssr: false });
interface OnboardingContextType {
startTour: (group?: OnboardingGroup, startIndex?: number) => void;
stopTour: () => void;
Expand Down
4 changes: 0 additions & 4 deletions src/components/PageContainer/PageContainer.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@
margin-inline-start: auto;
margin-inline-end: auto;

@include breakpoints.smallerThanTablet {
margin-block-start: var(--spacing-mega);
}

--flow-side-spacing: var(--spacing-small);
padding-inline-start: var(--flow-side-spacing);
padding-inline-end: var(--flow-side-spacing);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,6 @@

.spaceOnTop {
padding-block-start: calc(3.5 * var(--spacing-mega));
@include breakpoints.smallerThanTablet {
padding-block-start: calc(4.5 * var(--spacing-mega));
}
@include breakpoints.tablet {
padding-block-start: calc(3.5 * var(--spacing-mega));
}
}

.chapterNumber {
Expand Down
Loading
Loading