Skip to content

Commit

Permalink
feat(firebase, lanuage): develop
Browse files Browse the repository at this point in the history
  • Loading branch information
nu5rim3 committed Nov 19, 2023
1 parent b81d024 commit 6425b88
Show file tree
Hide file tree
Showing 39 changed files with 1,286 additions and 450 deletions.
266 changes: 138 additions & 128 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@mui/icons-material": "^5.11.16",
"@mui/lab": "^5.0.0-alpha.129",
"@mui/material": "^5.13.0",
"@mui/x-data-grid": "^6.18.1",
"@mui/x-date-pickers": "^6.5.0",
"@react-query-firebase/auth": "^1.0.0-dev.2",
"@react-query-firebase/firestore": "^1.0.0-dev.7",
Expand All @@ -21,18 +22,16 @@
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"dayjs": "^1.11.7",
<<<<<<< HEAD
"firebase": "^9.22.0",
=======
"firebase": "^9.22.1",
>>>>>>> b00e688e0d29e28a789fcf6650a9874b39124e41
"formik": "^2.2.9",
"i18next": "^23.7.6",
"lodash": "^4.17.21",
"qrcode": "^1.5.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-firebase-hooks": "^5.1.1",
"react-i18next": "^13.5.0",
"react-pageflip": "^2.0.3",
"react-query": "^3.39.3",
"react-redux": "^8.0.5",
Expand All @@ -42,6 +41,7 @@
"react-toastify": "^9.1.3",
"redux": "^4.2.1",
"typescript": "^4.4.2",
"uuid": "^9.0.0",
"web-vitals": "^2.1.0",
"yup": "^1.1.1"
},
Expand Down Expand Up @@ -74,6 +74,7 @@
"npm": "9.5.1"
},
"devDependencies": {
"@types/lodash": "^4.14.192"
"@types/lodash": "^4.14.192",
"@types/uuid": "^9.0.3"
}
}
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<title>Let's Cheers</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
16 changes: 10 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ import Routes from './routes';
import CssBaseline from '@mui/material/CssBaseline/CssBaseline';
import { Suspense } from 'react';
import Loader from './components/Loader';
import { I18nextProvider } from 'react-i18next';
import i18n from './utils/localization/i18n';

function App() {

return (
<ThemeProvider>
<CssBaseline />
<Suspense fallback={<Loader />}>
<Routes />
</Suspense>
</ThemeProvider>
<I18nextProvider i18n={i18n}>
<ThemeProvider>
<CssBaseline />
<Suspense fallback={<Loader />}>
<Routes />
</Suspense>
</ThemeProvider>
</I18nextProvider>
);
}

Expand Down
3 changes: 1 addition & 2 deletions src/components/FullModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ interface FullmodalProps {
open: boolean,
title: string,
toggleModal: () => void,
onSubmit: () => void,
children: React.ReactNode
}

const FullModal: React.FC<FullmodalProps> = ({ open, title, toggleModal, children, onSubmit }) => {
const FullModal: React.FC<FullmodalProps> = ({ open, title, toggleModal, children }) => {


return (
Expand Down
26 changes: 14 additions & 12 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ interface HeaderProps {
title: string,
primaryActionTitle?: string,
secondayActionTitle?: string,
onAddClick: () => void,
onEditClick: () => void,
onAddClick?: () => void,
onEditClick?: () => void,
}

const Header: React.FC<HeaderProps> = memo(({ title, primaryActionTitle, secondayActionTitle, onAddClick, onEditClick }) => {
Expand All @@ -34,16 +34,18 @@ const Header: React.FC<HeaderProps> = memo(({ title, primaryActionTitle, seconda
</Typography>
</Grid>
<Grid item xs={12} sm={6} display={'flex'} justifyContent={sm ? 'flex-end' : 'flex-start'}>
<Box mr={1}>
<Button
color='primary'
variant='outlined'
startIcon={<ModeEditOutlineIcon />}
onClick={onEditClick}
>
{secondayActionTitle}
</Button>
</Box>
{onEditClick &&
<Box mr={1}>
<Button
color='primary'
variant='outlined'
startIcon={<ModeEditOutlineIcon />}
onClick={onEditClick}
>
{secondayActionTitle}
</Button>
</Box>
}
<Box>
<Button
color='primary'
Expand Down
77 changes: 77 additions & 0 deletions src/components/Search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import styled from '@emotion/styled';
import { alpha, IconButton, InputBase, OutlinedInput } from '@mui/material';
import SearchIcon from '@mui/icons-material/Search';
import RestartAltIcon from '@mui/icons-material/RestartAlt';
import React, { useEffect, useState } from 'react'

interface ISearchBox {
dataSource?: any[];
setDataSource?: (data: any) => void;
}

const SearchBox: React.FC<ISearchBox> = ({ dataSource, setDataSource }) => {

const [searchKey, setSearchKey] = useState<string>("");
const originalDataSource: any[] = dataSource ?? [];


const onReset = () => {
setSearchKey("");
setDataSource && setDataSource(originalDataSource);
}

const filterDataSourceBysearchKey = () => {
// Escape special characters in the searchKey to build a valid regular expression
const escapedSearchKey = searchKey.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');

// Create a regular expression pattern that matches strings starting with the searchKey
const regexPattern = new RegExp(`^${escapedSearchKey}`, 'i');

const filter: any[] = dataSource?.filter((item: any) => regexPattern.test(item.name)) ?? []
setDataSource && setDataSource(filter);
}

useEffect(() => {
if (searchKey === "") {
setDataSource && setDataSource(originalDataSource);
} else {
filterDataSourceBysearchKey()
}

}, [searchKey])


return (
<div>
<OutlinedInput
value={searchKey}
sx={{ my: 1, flex: 1 }}
placeholder="Search By Name"
inputProps={{ 'aria-label': 'search by name' }}
onChange={(e) => setSearchKey(e.target.value)}
/>
{searchKey !== "" &&
<IconButton
aria-label="search"
color='primary'
sx={{ mx: 1 }}
onClick={onReset}
>
<RestartAltIcon />
</IconButton>
}

<IconButton
aria-label="search"
color='primary'
sx={{ mx: 1 }}
disabled={searchKey === ""}
onClick={filterDataSourceBysearchKey}
>
<SearchIcon />
</IconButton>
</div>
)
}

export default SearchBox;
14 changes: 7 additions & 7 deletions src/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ const routePath: IRoutePath[] = [
active: true,
level: 0
},
// {
// label: 'Foods',
// path: '/foods',
// icon: <DinnerDiningIcon />,
// active: false,
// level: 0
// },
{
label: 'Foods',
path: '/foods',
icon: <DinnerDiningIcon />,
active: true,
level: 0
},
// {
// label: 'Beverages',
// path: '/beverages',
Expand Down
11 changes: 5 additions & 6 deletions src/firebase/index.tsx → src/firebase/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@ import { getAnalytics } from "firebase/analytics";
import { getAuth, GoogleAuthProvider } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
import { getStorage } from "firebase/storage";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
import { getDatabase } from "firebase/database";

// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "AIzaSyCqlhGvLG1Xu5PgYiGrgkY9CYaNLOtanMo",
authDomain: "cheers-2002d.firebaseapp.com",
projectId: "cheers-2002d",
storageBucket: "cheers-2002d.appspot.com",
messagingSenderId: "112786245501",
appId: "1:112786245501:web:81db0a4512be635e372e14",
measurementId: "G-V61D58F8QQ"
measurementId: "G-V61D58F8QQ",
databaseURL: "https://cheers-2002d-default-rtdb.asia-southeast1.firebasedatabase.app"
};

// Initialize Firebase
Expand All @@ -26,4 +24,5 @@ const analytics = getAnalytics(app);
export const auth = getAuth();
export const googleProvider = new GoogleAuthProvider();
export const db = getFirestore(app);
export const storage = getStorage(app);
export const storage = getStorage(app);
export const database = getDatabase(app);
119 changes: 119 additions & 0 deletions src/firebase/services/food.services.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { collection, addDoc, doc, getDoc, getDocs, setDoc, query, where } from 'firebase/firestore';
import { db } from '..';

const collectionName: string = 'foods';

const useFoodServices = () => {
/**
* save
* @param payload
*/
const save = async (payload: IFood) => {
try {
await addDoc(collection(db, collectionName), payload)
.then((docRef: any) => {
console.log(`[SUCCESS][SAVE]| ${collectionName} written with ID: `, docRef.id);
return docRef.id;
})
.catch((error: any) => {
console.error(`[ERROR][SAVE] | ${collection}: `, error);
});
} catch (error) {
console.error(`[ERROR][SAVE] | ${collectionName} : `, error);
}
};

/**
* get List full
*/
const getList = async () => {
try {
await getDocs(collection(db, collectionName))
.then((res: any) => {
const documents = res.docs.map((doc: { data: () => any }) => doc.data());
console.log(`[SUCCESS][GET] | ${collectionName} : `, documents);
return documents;
})
.catch((error: any) => {
console.error(`[ERROR][GET] | ${collectionName} : `, error);
});
} catch (error) {
console.error(`[ERROR][GET] | ${collectionName} : `, error);
}
};

/**
* get signle data by id
* @param id
*/
const getById = async (id: string) => {
try {
const docRef = doc(db, collectionName, id);
await getDoc(docRef)
.then((resDoc: any) => {
if (resDoc.exists()) {
const response = resDoc.data();
console.log(`[SUCCESS][GETBYIT] | ${collectionName} : `, response);
return response;
} else {
console.log(`[SUCCESS][GETBYIT] | ${collectionName} : Document does not exist`);
}
})
.catch((error: any) => {
console.error(`[ERROR][GETBYID] | ${collectionName} : `, error);
});
} catch (error) {
console.error(`[ERROR][GETBYID] | ${collectionName} : `, error);
}
};

/**
* update single data by id
* @param id
* @param pyaload
*/
const updateById = async (id: string, pyaload: IFood) => {
try {
const docRef = doc(db, collectionName, id);
await setDoc(docRef, pyaload, { merge: true })
.then((resDoc: any) => {
console.log(`[SUCCESS][UPDATE] | ${collectionName} : Document updated successfully`);
})
.catch((error: any) => {
console.error(`[ERROR][UPDATE] | ${collectionName} : `, error);
});
} catch (error) {
console.error(`[ERROR][UPDATE] | ${collectionName} : `, error);
}
};

/**
* get list data by user id
* @param uid
* @returns
*/
const getListByUserId = async (uid: string) => {
const qry = query(collection(db, collectionName), where('uid', '==', uid));
try {
const querySnapshot = await getDocs(qry);
if (!querySnapshot.empty) {
const response = querySnapshot.docs.map((doc) => {
return { id: doc.id, ...doc.data() };
});
console.log(`[SUCCESS][GETBYIT] | ${collectionName} : `, response);
return response;
} else {
console.log(`[SUCCESS][GETBYIT] | ${collectionName} : Document does not exist`);
return [];
}
} catch (error) {
console.error(`[ERROR][GET] | ${collectionName} : `, error);
// You might want to throw the error here or handle it as needed
throw error;
}
};

return { save, getList, getById, updateById, getListByUserId };
};

export default useFoodServices;
Loading

1 comment on commit 6425b88

@vercel
Copy link

@vercel vercel bot commented on 6425b88 Nov 19, 2023

Choose a reason for hiding this comment

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

Please sign in to comment.