Skip to content

Commit

Permalink
Merge pull request #66 from AndyOooh/ED1-47-fix-create-event-button
Browse files Browse the repository at this point in the history
Ed1 47 fix create event button
  • Loading branch information
AndyOooh authored Jan 20, 2024
2 parents 6099612 + 308f7bf commit f571eaf
Show file tree
Hide file tree
Showing 23 changed files with 134 additions and 59 deletions.
21 changes: 0 additions & 21 deletions apps/app/src/app/(protected)/components/HomeMain/HomeMain.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,11 @@
'use client';

import React from 'react';
import { Stats } from './stats/Stats';
import { ReferralAd } from './referralAd/ReferralAd';
import { createDocument } from '__firebase/utilities';

export const HomeMain = () => {
const submitHandler = async () => {
try {
console.log('submitHandler');
await createDocument('emul-test', { test: 'it works' });
console.log('Check the database');
} catch (error) {
console.log('🚀 file: HomeMain.tsx:17 error:', error);
}
};

return (
// <div className='flex-1 bg-green-200/20'>
<div className='flex-1 flex flex-col gap-8 p-5'>
<Stats />
<ReferralAd />

{process.env.NEXT_PUBLIC_EMULATORS_ON === 'true' && (
<button className='btn' onClick={submitHandler}>
Test Emulator
</button>
)}
</div>
);
};
4 changes: 2 additions & 2 deletions apps/app/src/app/(protected)/events/Events.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export const EventsLala = ({ events }: Props) => {
<button
type='button'
// className='relative h-6 w-12'
className='btn btn-sm btn-info'
className='btn btn-sm btn-info w-16'
// onClick={() => onUpdateRole(index)}
>
Apply
Expand All @@ -181,7 +181,7 @@ export const EventsLala = ({ events }: Props) => {
</button>
<button
type='button'
className='btn btn-sm btn-error'
className='btn btn-sm btn-error w-16'
// onClick={() => onRemoveRole(index)}
>
Save
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use client';

import { CurrUserContext } from 'app/(protected)/components/Providers/CurrentUserProvider';
import Link from 'next/link';
import React, { useContext } from 'react';

export const CreateEventButton = () => {
const { currentUser } = useContext(CurrUserContext);
console.log('😍😍😍😍 currentUser:', currentUser);
return currentUser?.customClaims.type === 'business' ? (
<Link href={'/events/create'} className='btn'>
Create Event
</Link>
) : null;
};
28 changes: 24 additions & 4 deletions apps/app/src/app/(protected)/events/create/form/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
'use client';

import React, { useContext, useEffect } from 'react';
import { addDoc, arrayUnion, collection, doc, updateDoc } from 'firebase/firestore';
import { addDoc, arrayUnion, collection, doc, increment, updateDoc } from 'firebase/firestore';
import { DevTool } from '@hookform/devtools';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';

import { CurrUserContext } from 'app/(protected)/components/Providers/CurrentUserProvider';
import { onError, onTestForm } from '__utils/helpers';
import { db } from '__firebase/clientApp';
import { db, getCloudFunction } from '__firebase/clientApp';
import { ActionButton } from 'ui';
import { EventInfo } from './event-info';
import { IcreateEventSchema, createEventSchema } from './validation';
Expand Down Expand Up @@ -36,7 +36,21 @@ export const CreateEventForm = () => {
try {
// Step 1: Add a new entry to the "events" collection
const eventsCollectionRef = collection(db, 'events');
const newEventRef = await addDoc(eventsCollectionRef, data);

/*
* Fetch metaData/events doc to get currentId for events.
* Perhaps this can be done using const eventsDocRef = doc(db, 'metaData', 'events') ??
*/
const fetchDocById = getCloudFunction('fetchDocById');
const { data: eventsMetadata }: any = await fetchDocById({
collectionName: 'metaData',
id: 'events',
});

const newEventRef = await addDoc(eventsCollectionRef, {
...data,
event_id: eventsMetadata.currentId + 1,
});

// Step 2: Get the reference to the newly created event
const eventDocId = newEventRef.id;
Expand All @@ -47,6 +61,12 @@ export const CreateEventForm = () => {
events: arrayUnion({ eventId: eventDocId }),
});

/* update metaData/events */
const eventsDocRef = doc(db, 'metaData', 'events');
await updateDoc(eventsDocRef, {
currentId: increment(1),
});

console.log('Event submitted successfully!');
} catch (error) {
console.error('Error submitting event:', error);
Expand Down Expand Up @@ -106,7 +126,7 @@ export const CreateEventForm = () => {
)}
</div>
</form>
<DevTool control={control} />
{process.env.NODE_ENV === 'development' && <DevTool control={control} />}
</>
) : null;
};
6 changes: 1 addition & 5 deletions apps/app/src/app/(protected)/events/create/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import Link from 'next/link';
import React from 'react';
import { CreateEventForm } from './form';

type Props = {};

export default function CreateEvent({}: Props) {
export default function CreateEvent() {
return (
<div className='flex flex-col gap-4 w-full'>
<h1 className='text-3xl'>Create a new event</h1>
Expand Down
16 changes: 8 additions & 8 deletions apps/app/src/app/(protected)/events/page.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import 'server-only';

import { getCloudFunction } from '__firebase/clientApp';
import Link from 'next/link';
import { EventsLala } from './Events';
import { CreateEventButton } from './components/create-event-button';

type Props = {};

export default async function Events({}: Props) {
const fetchDocs = getCloudFunction('fetchDocs');
const { data } = await fetchDocs({ collectionName: 'events' });

const fetchDocsWithQuery = getCloudFunction('fetchDocsWithQuery');
const { data } = await fetchDocsWithQuery({ collectionName: 'events' });

return (
<div className='flex flex-col gap-4 w-full'>
<h1 className='text-3xl'>Upcoming Events</h1>
<div className='flex justify-between'>
<h1 className='text-3xl'>Upcoming Events</h1>
<CreateEventButton />
</div>
<div className='flex flex-col'></div>
<Link href={'/events/create'} className='btn'>
Create New Event
</Link>

<div className='w-full flex flex-col items-center justify-center gap-6'>
<EventsLala events={data as any[]} />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const EditProfileForm = () => {
mode: 'onTouched',
resolver: yupResolver(personalInfoSchema({ initialEmail: currentUser?.email })),
});
const { errors, isDirty, isValid, isSubmitting, isSubmitSuccessful, dirtyFields } = formState;
const { errors, isDirty, isValid, isSubmitting, isSubmitSuccessful } = formState;

useEffect(() => {
if (isSubmitSuccessful) {
Expand Down Expand Up @@ -84,7 +84,7 @@ export const EditProfileForm = () => {
)}
</div>
</form>
<DevTool control={control} />
{process.env.NODE_ENV === 'development' && <DevTool control={control} />}
</>
) : null;
};
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export const ChangePasswordForm = () => {
</div>
</div>
</div>
<DevTool control={control} />
{process.env.NODE_ENV === 'development' && <DevTool control={control} />}
</>
) : null;
};
22 changes: 22 additions & 0 deletions apps/app/src/app/(protected)/test-emulator/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { createDocument } from '__firebase/utilities';

export default function TestEmulatorPage() {
const submitHandler = async () => {
try {
console.log('submitHandler');
await createDocument('emul-test', { id: 123, test: 'it works' });
} catch (error) {
console.log('🚀 file: HomeMain.tsx:17 error:', error);
}
};
return (
<div className='flex flex-col gap-4 w-full'>
<h1 className='text-3xl'>Test Emulator Page</h1>
{process.env.NEXT_PUBLIC_EMULATORS_ON === 'true' && (
<button className='btn' onClick={submitHandler}>
Test Emulator
</button>
)}
</div>
);
}
23 changes: 19 additions & 4 deletions apps/app/src/components/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { BiHome, BiSearchAlt, BiDollarCircle, BiCalendarCheck, BiCog } from 'react-icons/bi';
import {
BiHome,
BiSearchAlt,
BiDollarCircle,
BiCalendarCheck,
BiCog,
BiTestTube,
} from 'react-icons/bi';
import Image from 'next/image';
import combi_mint from '/public/logo/combi/combi_mint.png';
import Link from 'next/link';
// import { useState } from 'react';

type Props = {};

Expand Down Expand Up @@ -59,11 +65,20 @@ function Sidebar({}: Props) {
<span className='title'>{item.title}</span>
</a>
))}
{process.env.NEXT_PUBLIC_EMULATORS_ON === 'true' && (
<a
key={'emulator-test'}
href={'/emulator-test'}
className='text-xs pl-2 mb-2 hover:scale-110 hover:font-semibold'>
<span className=''>
<BiTestTube size={iconSize} />
</span>
<span className='title'>Emulator Test</span>
</a>
)}
</li>
</ul>
</aside>
// <div></div>
// </div>
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"kind":"identitytoolkit#DownloadAccountResponse","users":[{"localId":"DI4Dx3YiiDonUcaz0UiiFjdCUkAU","createdAt":"1704033339723","lastLoginAt":"1704033339727","displayName":"Orange Chicken","photoUrl":"http://localhost:9199/v0/b/event-dee-staging.appspot.com/o/users%2FDI4Dx3YiiDonUcaz0UiiFjdCUkAU%2Fimages%2Fprofile?alt=media&token=aaa55962-ac74-4b1d-8045-7c688f925cc4","customAttributes":"{\"basic_info_done\":true,\"type\":\"freelancer\"}","providerUserInfo":[{"providerId":"google.com","rawId":"6233296176568572704053954672800598602635","federatedId":"6233296176568572704053954672800598602635","displayName":"Orange Chicken","email":"[email protected]","screenName":"chicken_orange"}],"validSince":"1705214817","email":"[email protected]","emailVerified":true,"disabled":false},{"localId":"XobXVTMfKX21NwEP7V5LEuuX4q8u","createdAt":"1704023132744","lastLoginAt":"1704023132744","photoUrl":"http://localhost:9199/v0/b/event-dee-staging.appspot.com/o/users%2FXobXVTMfKX21NwEP7V5LEuuX4q8u%2Fimages%2Fprofile?alt=media&token=be3f3bef-d833-4dd0-b275-11a58ec238a3","passwordHash":"fakeHash:salt=fakeSaltUu0sqgKGXdW18M52lrCJ:password=oooooo","salt":"fakeSaltUu0sqgKGXdW18M52lrCJ","passwordUpdatedAt":1705214817929,"customAttributes":"{\"basic_info_done\":true,\"type\":\"freelancer\"}","providerUserInfo":[{"providerId":"password","email":"[email protected]","federatedId":"[email protected]","rawId":"[email protected]","photoUrl":"http://localhost:9199/v0/b/event-dee-staging.appspot.com/o/users%2FXobXVTMfKX21NwEP7V5LEuuX4q8u%2Fimages%2Fprofile?alt=media&token=be3f3bef-d833-4dd0-b275-11a58ec238a3"}],"validSince":"1705214817","email":"[email protected]","emailVerified":false,"disabled":false},{"localId":"qIsokoD9bxhWt2tcFdcNpAg0DPZb","createdAt":"1704107208217","lastLoginAt":"1704912527992","photoUrl":"https://storage.cloud.google.com/event-dee-staging.appspot.com/misc/profile-photo-placeholder.jpg","passwordHash":"fakeHash:salt=fakeSalth89eFQSxrdhCytX68Nxe:password=bbbbbb","salt":"fakeSalth89eFQSxrdhCytX68Nxe","passwordUpdatedAt":1705214817929,"customAttributes":"{\"basic_info_done\":true,\"type\":\"business\"}","providerUserInfo":[{"providerId":"password","email":"[email protected]","federatedId":"[email protected]","rawId":"[email protected]","photoUrl":"https://storage.cloud.google.com/event-dee-staging.appspot.com/misc/profile-photo-placeholder.jpg"}],"validSince":"1705214817","email":"[email protected]","emailVerified":false,"disabled":false}]}
{"kind":"identitytoolkit#DownloadAccountResponse","users":[{"localId":"DI4Dx3YiiDonUcaz0UiiFjdCUkAU","createdAt":"1704033339723","lastLoginAt":"1704033339727","displayName":"Orange Chicken","photoUrl":"http://localhost:9199/v0/b/event-dee-staging.appspot.com/o/users%2FDI4Dx3YiiDonUcaz0UiiFjdCUkAU%2Fimages%2Fprofile?alt=media&token=aaa55962-ac74-4b1d-8045-7c688f925cc4","customAttributes":"{\"basic_info_done\":true,\"type\":\"freelancer\"}","providerUserInfo":[{"providerId":"google.com","rawId":"6233296176568572704053954672800598602635","federatedId":"6233296176568572704053954672800598602635","displayName":"Orange Chicken","email":"[email protected]","screenName":"chicken_orange"}],"validSince":"1705773834","email":"[email protected]","emailVerified":true,"disabled":false},{"localId":"XobXVTMfKX21NwEP7V5LEuuX4q8u","createdAt":"1704023132744","lastLoginAt":"1704023132744","photoUrl":"http://localhost:9199/v0/b/event-dee-staging.appspot.com/o/users%2FXobXVTMfKX21NwEP7V5LEuuX4q8u%2Fimages%2Fprofile?alt=media&token=be3f3bef-d833-4dd0-b275-11a58ec238a3","passwordHash":"fakeHash:salt=fakeSaltUu0sqgKGXdW18M52lrCJ:password=oooooo","salt":"fakeSaltUu0sqgKGXdW18M52lrCJ","passwordUpdatedAt":1705773834089,"customAttributes":"{\"basic_info_done\":true,\"type\":\"freelancer\"}","providerUserInfo":[{"providerId":"password","email":"[email protected]","federatedId":"[email protected]","rawId":"[email protected]","photoUrl":"http://localhost:9199/v0/b/event-dee-staging.appspot.com/o/users%2FXobXVTMfKX21NwEP7V5LEuuX4q8u%2Fimages%2Fprofile?alt=media&token=be3f3bef-d833-4dd0-b275-11a58ec238a3"}],"validSince":"1705773834","email":"[email protected]","emailVerified":false,"disabled":false},{"localId":"qIsokoD9bxhWt2tcFdcNpAg0DPZb","createdAt":"1704107208217","lastLoginAt":"1705774752210","photoUrl":"https://storage.cloud.google.com/event-dee-staging.appspot.com/misc/profile-photo-placeholder.jpg","passwordHash":"fakeHash:salt=fakeSalth89eFQSxrdhCytX68Nxe:password=bbbbbb","salt":"fakeSalth89eFQSxrdhCytX68Nxe","passwordUpdatedAt":1705773834089,"customAttributes":"{\"basic_info_done\":true,\"type\":\"business\"}","providerUserInfo":[{"providerId":"password","email":"[email protected]","federatedId":"[email protected]","rawId":"[email protected]","photoUrl":"https://storage.cloud.google.com/event-dee-staging.appspot.com/misc/profile-photo-placeholder.jpg"}],"validSince":"1705773834","email":"[email protected]","emailVerified":false,"disabled":false,"lastRefreshAt":"2024-01-20T19:06:09.807Z"}]}
Binary file not shown.
Binary file not shown.
Binary file not shown.
50 changes: 39 additions & 11 deletions apps/firebase-cloud-functions/src/fetch-firestore-data.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
import { https } from 'firebase-functions';
import { WhereFilterOp } from '@google-cloud/firestore';
import { db } from '.';
import { DocumentData } from 'firebase-admin/firestore';

type Params = {
type DocData = { id: string; [key: string]: any };

type FetchDocsWithQueryParams = {
collectionName: string;
field?: string;
operator?: WhereFilterOp;
value?: any;
limit?: number;
};

type DocumentData = { id: string; [key: string]: any };

type Return = Promise<DocumentData[]>;

/**
* Fetch documents based on a query or fetch entire collection.
* @param {string} collectionName - Name of the Firestore collection.
* @param {string} [field] - Field to query on.
* @param {WhereFilterOp} [operator] - Query operator (e.g., '==', '>', '<').
* @param {any} [value] - Value to compare in the query.
* @param {number} [limit] - Number of documents to limit the result to.
* @returns {Promise<Array>} - Array of documents matching the query or the entire collection.
* @returns {Promise<DocData[]>} - Array of documents matching the query or the entire collection.
*/
export const fetchDocs = https.onCall(
async ({ collectionName, field, operator, value, limit = 10 }: Params): Return => {
export const fetchDocsWithQuery = https.onCall(
async ({
collectionName,
field,
operator,
value,
limit = 10,
}: FetchDocsWithQueryParams): Promise<DocData[]> => {
try {
console.log('in fetchDocs 😍😂😍😂😍😂😍😂😍😂😍😂😍😂');

Expand All @@ -37,7 +42,7 @@ export const fetchDocs = https.onCall(
.limit(limit || Infinity)
.get();

const documents: DocumentData[] = [];
const documents: DocData[] = [];
querySnapshot.forEach(doc => {
documents.push({ id: doc.id, ...doc.data() });
});
Expand All @@ -48,7 +53,7 @@ export const fetchDocs = https.onCall(
// Fetch entire collection
const querySnapshot = await collectionRef.limit(limit).get();

const documents: DocumentData[] = [];
const documents: DocData[] = [];
querySnapshot.forEach(doc => {
documents.push({ id: doc.id, ...doc.data() });
});
Expand All @@ -57,7 +62,30 @@ export const fetchDocs = https.onCall(
return documents;
}
} catch (error) {
console.error('Error fetching documents:', error);
console.error('Error fetching documents, fetchDocsWithQuery:', error);
throw new https.HttpsError('internal', 'Error fetching documents', error);
}
}
);

type fetchDocByIdParams = {
collectionName: string;
id: string;
};

export const fetchDocById = https.onCall(
async ({ collectionName, id }: fetchDocByIdParams): Promise<DocumentData> => {
try {
const collectionRef = db.collection(collectionName);

const querySnapshot = await collectionRef
.doc(id) // Assuming 'value' is the document ID
.get();

const document = querySnapshot.data()!;
return document;
} catch (error) {
console.error('Error fetching documents, fetchDocById:', error);
throw new https.HttpsError('internal', 'Error fetching documents', error);
}
}
Expand Down

2 comments on commit f571eaf

@vercel
Copy link

@vercel vercel bot commented on f571eaf Jan 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

dev-event-dee2 – ./apps/app

dev-event-dee2-andyoooh.vercel.app
dev-event-dee2.vercel.app
dev-event-dee2-git-main-andyoooh.vercel.app

@vercel
Copy link

@vercel vercel bot commented on f571eaf Jan 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

app-event-dee2 – ./apps/app

app-event-dee2.vercel.app
app-event-dee2-git-main-andyoooh.vercel.app
app-event-dee2-andyoooh.vercel.app

Please sign in to comment.