Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ coverage
!.vscode/launch.json
!.vscode/extensions.json

# misc
# express-server
apps/express-server/public
apps/express-server/uploads

Expand Down
5 changes: 4 additions & 1 deletion apps/express-server/.env_sample
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,7 @@ AWS_SQS_FIFO_URL=
AWS_SNS_TOPIC_ARN=

# Stripe
STRIPE_SECRET_KEY=
STRIPE_SECRET_KEY=

# Firebase
FIREBASE_API_KEY=
Empty file.
11 changes: 1 addition & 10 deletions apps/next-client/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,9 @@ const compat = new FlatCompat({

const eslintConfig = [
...jsConfig,
...nextTsConfig,
// ...nextTsConfig,
...nextConfig,
...compat.extends('next/core-web-vitals', 'next/typescript'),
{
/**
* Somehow loading this rule is causing issues, when using
* NextApp in monorepo, thus disabling this for now.
*/
rules: {
'@typescript-eslint/no-empty-function': 'off'
}
}
];

export default eslintConfig;
6 changes: 5 additions & 1 deletion apps/next-client/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import createMDX from '@next/mdx';
import createNextIntlPlugin from 'next-intl/plugin';
import { withSentryConfig } from '@sentry/nextjs';

const withNextIntl = createNextIntlPlugin();
/**
* By default, it expects i18n/request.ts to be directly under
* the "src" folder.
*/
const withNextIntl = createNextIntlPlugin('./src/services/i18n/request.ts');

/** @type {import('next').NextConfig} */
const nextConfig = {
Expand Down
4 changes: 3 additions & 1 deletion apps/next-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"@sentry/nextjs": "^9",
"@tanstack/react-table": "^8.21.3",
"axios": "^1.8.4",
"firebase": "^11.6.0",
"firebaseui": "^6.1.0",
"graphql": "^16.10.0",
"graphql-hooks": "^8.2.0",
"graphql-hooks-memcache": "^3.2.0",
Expand All @@ -40,8 +42,8 @@
"@nish1896/eslint-flat-config": "^2.0.4",
"@sentry/cli": "^2.43.0",
"@tailwindcss/postcss": "^4.1.4",
"@types/mixpanel-browser": "^2.54.0",
"@types/mdx": "^2.0.13",
"@types/mixpanel-browser": "^2.54.0",
"@types/node": "^22.14.1",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import { ClientContext } from 'graphql-hooks';
import { datoCmsClient } from '@/graphql/client';
import { datoCmsClient } from '@/services/graphql/client';

type LayoutProps = {
children: React.ReactNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Image from 'next/image';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import { PageHeading, Loading } from '@csl/shared-fe';
import { SingleStoreLocationsQuery } from '@/graphql/queries';
import { SingleStoreLocationsQuery } from '@/services/graphql/queries';

type Store = {
storeName: string;
Expand Down
26 changes: 23 additions & 3 deletions apps/next-client/src/app/[locale]/dato-cms/server-fetch/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
/**
* PS if I import from '@/services/graphql', it would give me
* an error, since this module also exports GraphQLClient which
* is a client component and not compatible with server components.
*/
import { Fragment } from 'react';
import Image from 'next/image';
import axios from 'axios';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import { ApiEndpoints, ENV_VARS } from '@/constants';
import { SingleStoreLocationsQuery } from '@/graphql/queries';
import { SingleStoreLocationsQuery } from '@/services/graphql/queries';

type StoreData = {
data: {
store: {
storeName: string;
storeImage: {
url: string;
responsiveImage: {
width: number;
height: number;
};
};
};
};
};

export default async function DatoCMSServerFetchPage() {
const response = await axios.post(
const response = await axios.post<StoreData>(
ApiEndpoints.datoCMS,
{ query: SingleStoreLocationsQuery },
{
Expand All @@ -24,7 +44,7 @@ export default async function DatoCMSServerFetchPage() {
<Typography sx={{ mb: '30px' }}>
Server side fetching using DatoCMS api
</Typography>
<Grid size={{ xs: 12 }}>
<Grid size={12}>
<Typography>
{storeInfo.store.storeName}
</Typography>
Expand Down
100 changes: 100 additions & 0 deletions apps/next-client/src/app/[locale]/firebase/auth/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
'use client';

import { useEffect } from 'react';
import firebase from 'firebase/compat/app';
import firebaseService from '@/services/firebase';
import 'firebaseui/dist/firebaseui.css';
import type firebaseui from 'firebaseui';

export default function FirebaseSignIn() {
const firebaseContainerId = 'firebase-auth-container';

/**
* https://www.npmjs.com/package/firebaseui
*
* firebaseui library is written in UMD style (Universal Module Definition),
* old style JS. Hence, we need to use `import * as` syntax to import it.
*/
useEffect(() => {
import('firebaseui').then(firebaseUI => {
const firebaseAuth = firebaseService.getAuthInstance();
const loggedUser = firebaseAuth.currentUser;
console.log('loggedUser: ', loggedUser);
const ui = firebaseUI.auth.AuthUI.getInstance() || new firebaseUI.auth.AuthUI(firebaseAuth);

/* https://www.npmjs.com/package/firebaseui#configuration */
const uiConfig: firebaseui.auth.Config = {
autoUpgradeAnonymousUsers: true,
signInSuccessUrl: '/firebase/auth/success',
signInOptions: [
firebase.auth.EmailAuthProvider.PROVIDER_ID,
{
provider: firebase.auth.GoogleAuthProvider.PROVIDER_ID,
scopes: [
'https://www.googleapis.com/auth/contacts.readonly'
],
customParameters: {
/* Forces account selection. */
prompt: 'select_account'
}
},
{
provider: firebase.auth.FacebookAuthProvider.PROVIDER_ID,
scopes: [
'public_profile',
'email',
'user_likes',
'user_friends'
],
customParameters: {
/* Forces password re-entry. */
auth_type: 'reauthenticate'
}
},
firebase.auth.TwitterAuthProvider.PROVIDER_ID,
firebase.auth.GithubAuthProvider.PROVIDER_ID,
{
provider: firebase.auth.PhoneAuthProvider.PROVIDER_ID,
recaptchaParameters: {
type: 'image',
size: 'normal',
badge: 'bottomleft'
},
defaultCountry: 'IN',
},
'apple.com',
'microsoft.com',
{
provider: 'yahoo.com',
fullLabel: 'Yahoo',
},
firebaseUI.auth.AnonymousAuthProvider.PROVIDER_ID,
],
callbacks: {
signInSuccessWithAuthResult: function(authResult, redirectUrl) {
console.log('redirectUrl: ', redirectUrl);
console.log('authResult: ', authResult);
return true;
},
uiShown: function() {
const loader = document.getElementById('loader');
if (loader) {
loader.style.display = 'none';
}
},
// @ts-ignore
signInFailure: function(error) {
if (error.code != 'firebaseui/anonymous-upgrade-merge-conflict') {
return Promise.resolve();
}
const cred = error.credential;
return firebase.auth().signInWithCredential(cred);
}
},
};
ui.start(`#${firebaseContainerId}`, uiConfig);
});
}, []);

return <div id={firebaseContainerId} />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function FirebaseAuthSuccessPage() {
return (
<div className="flex items-center justify-center">
<div className="text-3xl text-green-500 font-bold">Firebase Auth Success</div>
</div>
);
}
14 changes: 14 additions & 0 deletions apps/next-client/src/app/[locale]/firebase/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Fragment } from 'react';
import { PageHeading } from '@csl/shared-fe';
import { FirebasePageAnalytics } from '@/components';

export default function FirebasePage() {
return (
<Fragment>
<FirebasePageAnalytics
title="Firebase Page"
/>
<PageHeading title="Firebase" />
</Fragment>
);
}
4 changes: 2 additions & 2 deletions apps/next-client/src/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { AppRouterCacheProvider } from '@mui/material-nextjs/v14-appRouter';
import { ThemeProvider } from '@mui/material/styles';
import theme from '@/assets/styles/theme';
import { AppBar, MixPanelClient, PageContainer } from '@/components';
import { routing } from '@/i18n/routing';
import { i18nRouting } from '@/services/i18n';
import { type Locales } from '@/types';
import '../globals.css';

Expand Down Expand Up @@ -42,7 +42,7 @@ export default async function RootLayout({
}: RootLayoutProps) {
const { locale } = await params;
/* Ensure that the incoming `locale` is valid */
if (!routing.locales.includes(locale)) {
if (!i18nRouting.locales.includes(locale)) {
notFound();
}

Expand Down
4 changes: 2 additions & 2 deletions apps/next-client/src/app/api/airports/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type NextRequest, NextResponse } from 'next/server';
import { AirportModel } from '@csl/mongo-models';
import mongoDB from '@/mongoDB';
import mongoDBService from '@/services/mongoDB';
import { logApiError } from '@/utils';

export async function GET(request: NextRequest) {
Expand All @@ -11,7 +11,7 @@ export async function GET(request: NextRequest) {
const recordsPerPage = limit ? Number(limit) : 10;

try {
await mongoDB.connect();
await mongoDBService.connect();
const allData = await AirportModel.find()
.skip((pageNum - 1) * recordsPerPage)
.limit(recordsPerPage);
Expand Down
4 changes: 2 additions & 2 deletions apps/next-client/src/app/api/person/[id]/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { type NextRequest, NextResponse } from 'next/server';
import { Types } from 'mongoose';
import { PersonModel } from '@csl/mongo-models';
import mongoDB from '@/mongoDB';
import mongoDBService from '@/services/mongoDB';

type RequestParams = {
params: Promise<{ id: string }>;
Expand All @@ -14,7 +14,7 @@ type RequestParams = {
export async function GET(request: NextRequest, { params }: RequestParams) {
const { id } = await params;
try {
await mongoDB.connect();
await mongoDBService.connect();
const personDetails = await PersonModel.findOne({
_id: new Types.ObjectId(id)
});
Expand Down
4 changes: 2 additions & 2 deletions apps/next-client/src/app/api/person/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type NextRequest, NextResponse } from 'next/server';
import { PersonModel } from '@csl/mongo-models';
import mongoDB from '@/mongoDB';
import mongoDBService from '@/services/mongoDB';

export async function GET(request: NextRequest) {
/**
Expand All @@ -23,7 +23,7 @@ export async function GET(request: NextRequest) {
const recordsPerPage = limit ? Number(limit) : 10;

try {
await mongoDB.connect();
await mongoDBService.connect();
const allData = await PersonModel.find()
.skip((pageNum - 1) * recordsPerPage)
.limit(recordsPerPage);
Expand Down
4 changes: 2 additions & 2 deletions apps/next-client/src/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BaseLayout, NotFoundPage } from '@/components';
import { routing } from '@/i18n/routing';
import { i18nRouting } from '@/services/i18n';

/**
* This page renders when a route like `/unknown.txt` is requested.
Expand All @@ -9,7 +9,7 @@ import { routing } from '@/i18n/routing';

export default function GlobalNotFound() {
return (
<BaseLayout locale={routing.defaultLocale}>
<BaseLayout locale={i18nRouting.defaultLocale}>
<NotFoundPage />
</BaseLayout>
);
Expand Down
6 changes: 3 additions & 3 deletions apps/next-client/src/app/sitemap.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type MetadataRoute } from 'next';
import { host } from '@/config';
import { getPathname, routing } from '@/i18n/routing';
import { getPathname, i18nRouting } from '@/services/i18n';
import { type Locales } from '@/types';

type Href = Parameters<typeof getPathname>[0]['href'];
Expand All @@ -12,10 +12,10 @@ function getUrl(href: Href, locale: Locales) {

function getEntry(href: Href) {
return {
url: getUrl(href, routing.defaultLocale),
url: getUrl(href, i18nRouting.defaultLocale),
alternates: {
languages: Object.fromEntries(
routing.locales.map(locale => [locale, getUrl(href, locale)])
i18nRouting.locales.map(locale => [locale, getUrl(href, locale)])
)
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use client';

/**
* Since I want to enable analytics on all pages, this component can
* be used alongside other components on that page, while also ensuring
* that the page is rendered on the server side, if applicable.
*/
import { Fragment } from 'react';
import { usePathname } from 'next/navigation';
import { useFirebasePageView } from '@/hooks';

type FirebasePageAnalyticsProps = {
title: string;
};

export default function FirebasePageAnalytics ({
title,
}: FirebasePageAnalyticsProps) {
const pathname = usePathname();
console.log('pathname: ', pathname);
useFirebasePageView({
title,
path: pathname
});
return <Fragment />;
}
2 changes: 2 additions & 0 deletions apps/next-client/src/components/analytics/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as FirebasePageAnalytics } from './FirebasePageAnalytics';
export { default as MixPanelClient } from './MixPanelClient';
2 changes: 2 additions & 0 deletions apps/next-client/src/components/connection/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as OnlineStatusWrapper } from './OnlineStatusWrapper';
export { default as SocketConnection } from './SocketConnection';
Loading