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
6 changes: 6 additions & 0 deletions dear-diary/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
REACT_APP_API_KEY=AIzaSyBoO1cF3m--z1OKJUNaflL5drrTA0aebaE
REACT_APP_AUTH_DOMIAN=dear-diary-thusara-9535b.firebaseapp.com
REACT_APP_PROJECT_ID=dear-diary-thusara-9535b
REACT_APP_STORAGE_BUCKET=dear-diary-thusara-9535b.appspot.com
REACT_APP_SENDER_ID=458518884342
REACT_APP_APP_ID=1:458518884342:web:9b1c0526c179fbf82c21d7
Comment on lines +1 to +6

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

don't commit env values

1 change: 1 addition & 0 deletions dear-diary/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
.env.development.local
.env.test.local
.env.production.local
.env

npm-debug.log*
yarn-debug.log*
Expand Down
801 changes: 801 additions & 0 deletions dear-diary/package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions dear-diary/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
"@types/node": "^16.18.46",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"firebase": "^10.4.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.1.2",
"react-router-dom": "^6.15.0",
"react-scripts": "5.0.1",
"redux-saga": "^1.2.3",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
Expand Down
9 changes: 8 additions & 1 deletion dear-diary/src/components/DiaryForm/DiaryForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { TextField, Button, Container, Stack, Typography } from '@mui/material';
import type { RootState } from '../../redux/store/store';
import { useSelector, useDispatch } from 'react-redux';
import { addCard } from '../../redux/card/cardSlice';
import app from '../../firebase/setup';
import { collection, getFirestore, addDoc } from 'firebase/firestore';
const db = getFirestore(app);

const DiaryForm: React.FC = () => {
const [showForm, setShowForm] = useState(false);
Expand All @@ -15,7 +18,7 @@ const DiaryForm: React.FC = () => {
setShowForm(true);
};

const handleSubmit = (event: React.FormEvent) => {
async function handleSubmit(event: React.FormEvent): Promise<void> {
event.preventDefault();
const formData = new FormData(event.target as HTMLFormElement);
const title = (formData.get('title') || '').toString();
Expand All @@ -40,6 +43,10 @@ const DiaryForm: React.FC = () => {
description,
};
dispatch(addCard(newDiaryEntry));

const docRef = await addDoc(collection(db, "cards"), newDiaryEntry);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

don't call APIs directly from the UI file, use saga to handle API calls

console.log("Document written with ID: ", docRef.id);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

remove unwanted logs


(event.target as HTMLFormElement).reset();
setShowForm(false);
}
Expand Down
62 changes: 42 additions & 20 deletions dear-diary/src/containers/DiaryHome/DiaryHome.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,52 @@
import React from 'react';
import React, { useEffect } from 'react';
import { Container, Grid, Box } from '@mui/material';
import DiaryCard from '../../components/DiaryCard/DiaryCard';
import PrimaryAppBar from '../../components/AppBar/AppBar';
import DiaryForm from '../../components/DiaryForm/DiaryForm';
import type { RootState } from '../../redux/store/store';
import { useSelector } from 'react-redux';
import { useSelector, useDispatch } from 'react-redux';
import app from '../../firebase/setup';
import { getFirestore, collection, query, onSnapshot } from 'firebase/firestore';
import { addCards } from '../../redux/card/cardSlice';

const db = getFirestore(app);

const DiaryHome: React.FC = () => {
const cards = useSelector((state: RootState) => state.cards.cards)
return (
<>
<PrimaryAppBar />
<Container sx={{ minHeight: '100vh', minWidth: '100vw', backgroundColor: '#42a5f5' }}>
<Box sx={{ paddingTop: '15vh' }}>
<DiaryForm />
<Grid container sx={{paddingTop: '5vh'}} columnSpacing={{ xs: 1, sm: 1, md: 1 }}>
{cards.map((card, index) => (
<Grid key={index} item xs={12} sm={6} md={3}>
<DiaryCard title={card.title} subtitle={card.username} description={card.description} />
</Grid>
))}
</Grid>
</Box>
</Container>
</>
);
const dispatch = useDispatch();

useEffect(() => {
const unsubscribe = onSnapshot(query(collection(db, 'cards')), (snapShot) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

move to saga

const cards = snapShot.docs.map((doc) => {
const { title, username, description } = doc.data();
return { title, username, description };
});
dispatch(addCards(cards));
});

return () => {
unsubscribe();
};
}, [dispatch]);


const cards = useSelector((state: RootState) => state.cards.cards)
return (
<>
<PrimaryAppBar />
<Container sx={{ minHeight: '100vh', minWidth: '100vw', backgroundColor: '#42a5f5' }}>
<Box sx={{ paddingTop: '15vh' }}>
<DiaryForm />
<Grid container sx={{paddingTop: '5vh'}} columnSpacing={{ xs: 1, sm: 1, md: 1 }}>
{cards.map((card, index) => (
<Grid key={index} item xs={12} sm={6} md={3}>
<DiaryCard title={card.title} subtitle={card.username} description={card.description} />
</Grid>
))}
</Grid>
</Box>
</Container>
</>
);
};

export default DiaryHome;
18 changes: 18 additions & 0 deletions dear-diary/src/firebase/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
console.log(process.env.REACT_APP_API_KEY)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

remove logs

const firebaseConfig = {
apiKey: process.env.REACT_APP_API_KEY,
authDomain: process.env.REACT_APP_AUTH_DOMAIN,
projectId: process.env.REACT_APP_PROJECT_ID,
storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_SENDER_ID,
appId: process.env.REACT_APP_APP_ID,
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
export default app;
19 changes: 16 additions & 3 deletions dear-diary/src/redux/card/cardSlice.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import Card from './card';
import { isEqual } from '../../utils/isEqual';

interface CardState {
cards: Card[];
Expand All @@ -14,11 +15,23 @@ export const cardSlice = createSlice({
initialState,
reducers: {
addCard: (state, action: PayloadAction<Card>) => {
state.cards.push(action.payload);
const newCard = action.payload;
const isUnique = state.cards.every((card) => !isEqual(card, newCard));

if (isUnique) {
state.cards.push(newCard);
}
},
addCards: (state, action: PayloadAction<Card[]>) => {
const newCards = action.payload;
const uniqueNewCards = newCards.filter((newCard) => {
return state.cards.every((card) => !isEqual(card, newCard));
});

state.cards.push(...uniqueNewCards);
},
},
});

export const { addCard } = cardSlice.actions;

export const { addCard, addCards } = cardSlice.actions;
export default cardSlice.reducer;
6 changes: 6 additions & 0 deletions dear-diary/src/utils/isEqual.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Compare objects for equality
function isEqual(objA: any, objB: any): boolean {
return JSON.stringify(objA) === JSON.stringify(objB);
}

export {isEqual};