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

Finished The Journaling Feature #3

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
Binary file modified backend/backend/__pycache__/settings.cpython-310.pyc
Binary file not shown.
10 changes: 4 additions & 6 deletions backend/backend/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = [
'192.168.254.10',
]


# Application definition

Expand All @@ -47,8 +43,8 @@
CORS_ALLOWED_ORIGINS = [
'http://localhost:5173',
'http://localhost:8081',
'exp://192.168.254.9:8081',
'http://192.168.254.9:8081',
'exp://192.168.254.26:8081',
'http://192.168.254.26:8081',
]

MIDDLEWARE = [
Expand Down Expand Up @@ -90,6 +86,8 @@
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases


# We're going to add different Databases in the future!
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
Expand Down
Binary file modified backend/db.sqlite3
Binary file not shown.
Binary file modified backend/journaling/api/__pycache__/serializers.cpython-310.pyc
Binary file not shown.
Binary file modified backend/journaling/api/__pycache__/urls.cpython-310.pyc
Binary file not shown.
Binary file modified backend/journaling/api/__pycache__/views.cpython-310.pyc
Binary file not shown.
3 changes: 2 additions & 1 deletion backend/journaling/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Meta:
class JournalPageSerializer(serializers.ModelSerializer):
class Meta:
model = JournalPage
fields = ['id', 'prompt', 'entry', 'image']
fields = ['id', 'journal', 'prompt', 'entry', 'image']


# Handling POST requests from our Frontend
Expand All @@ -26,3 +26,4 @@ class CreateJournalPage(serializers.ModelSerializer):
class Meta:
model = JournalPage
fields = ['journal_id', 'prompt', 'entry']

3 changes: 2 additions & 1 deletion backend/journaling/api/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import JournalViewSet, JournalPageViewSet, CreateJournalPageView, CreateJournalView
from .views import JournalViewSet, JournalPageViewSet, CreateJournalPageView, CreateJournalView, DeleteJournalView


journal_router = DefaultRouter()
Expand All @@ -11,4 +11,5 @@
path('', include(journal_router.urls)),
path('create_journal_page/', CreateJournalPageView.as_view()),
path('create_journal/', CreateJournalView.as_view()),
path('delete_journal/<int:journal_id>/', DeleteJournalView.as_view()),
]
9 changes: 9 additions & 0 deletions backend/journaling/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,12 @@ def post(self, request):
journal_page.save()
return Response(JournalPageSerializer(journal_page).data, status=status.HTTP_201_CREATED)
return Response({'Bad Request': 'Invalid data...'}, status=status.HTTP_400_BAD_REQUEST)

class DeleteJournalView(APIView):
def delete(self, request, journal_id):
journal = Journal.objects.get(id=journal_id)
try:
journal.delete()
return Response(JournalSerializer(journal).data, status=status.HTTP_204_NO_CONTENT)
except journal.DoesNotExist:
return Response({'Not Found': 'Journal not found.'}, status=status.HTTP_404_NOT_FOUND)
68 changes: 48 additions & 20 deletions frontendMobile/src/Api/apiEndpoints.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
// This is where all the API endpoints are handled (using a REST framework)
// I made sure to put them all in one file to make frontend dev and backend dev a lot easier!
// I made sure to put them all in one file to make frontend dev and backend dev communication a lot easier!

DOMAIN = 'BACKEND_SERVER' // Put the server to your backend here!
DOMAIN = 'http://192.168.254.26:8000' // Put the server to your backend here!

const endpoints = {
getJournal: `${DOMAIN}/api/journal`,
getJournalPage: `${DOMAIN}/api/journal_page`,
deleteJournal: `${DOMAIN}/api/delete_journal`,
journal: `${DOMAIN}/api/create_journal/`,
journalPage: `${DOMAIN}/api/create_journal_page/`,

handleApiResponse(endpoint, data, method = "POST", handleOk = () => {}, handleError = () => {}) {
postApiResponse(endpoint, data, handleOk = () => {}, handleError = () => {}) {
console.log("Sender's Data: ", data)

const requestOptions = {
method: method,
method: "POST",
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
};

fetch(endpoint, requestOptions)
.then((response) => {
if (!response.ok) {
throw new Error(` ${ data.data }`)
}
return response.json()})
.then((responseData) => {console.log(responseData);
if (responseData) {
handleOk(responseData);
} else {
console.warn("Response data does not have any properties:", responseData);
.then((response) => {
if (!response.ok) {
throw new Error(` ${ data.data }`)
}
return response.json()})
.then((responseData) => {console.log(responseData);
if (responseData) {
handleOk(responseData);
} else {
console.warn("Response data does not have any properties:", responseData);
handleError();
}
})
.catch((error) => {console.error("Error during fetch: ", error);
handleError();
}
})
.catch((error) => {console.error("Error during fetch: ", error);
handleError();
});
});
},

async getAPIResponse(endpoint, setData) {
Expand All @@ -49,7 +51,33 @@ const endpoints = {
} catch (error) {
console.error('Error fetching data:', error);
}
}
},

deleteApiResponse(endpoint, deleteId) {
const requestOptions = {
method: "DELETE",
headers: {
'Content-Type': 'application/json',
},
};

const specEndpoint = `${endpoint}/${deleteId}`;
fetch(specEndpoint, requestOptions)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
console.log('Deletion successful');
})
.then(data => {
console.log('Data:', data);
})
.catch(error => {
console.error('Error deleting data:', error);
});

},

};

export default endpoints;
32 changes: 32 additions & 0 deletions frontendMobile/src/Components/JournalPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { View, Text, TextInput, StyleSheet } from 'react-native';
import { mainStyle } from '../Styles/Styles';

const s = StyleSheet.create(mainStyle);

const JournalPage = ({type, pageData, setPageData, prompt}) => {
const handleChange = (name, value) => {
setPageData({
...pageData,
[name]: value,
});
};

return (
<View style={s.container}>
{type === "Empty Page" && <TextInput style={s.journal.emptyPrompt}
placeholder="Prompt"
value={pageData.prompt}
onChangeText={(text) => handleChange('prompt', text)}
/>}
{type !== "Empty Page" && <Text style={s.journal.promptText}>{prompt}</Text>}
<TextInput style={s.journal.entry}
placeholder="Entry"
value={pageData.entry}
multiline
onChangeText={(text) => handleChange('entry', text)}
/>
</View>
);
};

export default JournalPage;
27 changes: 27 additions & 0 deletions frontendMobile/src/Components/Warning.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { View, Text, StyleSheet, TouchableOpacity, Modal } from 'react-native';
import { mainStyle } from '../Styles/Styles';

const s = StyleSheet.create(mainStyle);

const Warning = ({ visible, onClose, warning, onAction }) => {
return (
<Modal
animationType="slide"
transparent
visible={visible}
onRequestClose={onClose}
>
<View style={s.journalChoices.container}>
<Text style={s.text}>{warning}</Text>
<TouchableOpacity onPress={onAction} style={s.button}>
<Text style={s.buttonText}>Delete</Text>
</TouchableOpacity>
<TouchableOpacity onPress={onClose} style={s.button}>
<Text style={s.buttonText}>Cancel</Text>
</TouchableOpacity>
</View>
</Modal>
);
};

export default Warning;
8 changes: 6 additions & 2 deletions frontendMobile/src/Navigators/HomeStackNavigator.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import HomeScreen from '../Screens/HomeScreen';
import JournalingScreen from '../Screens/JournalingScreen';
import ViewJournalsScreen from '../Screens/ViewJournalsScreen';
import JournalingScreen from '../Screens/Journaling/JournalingScreen';
import ViewJournalsScreen from '../Screens/Journaling/ViewJournalsScreen';
import ViewPagesScreen from '../Screens/Journaling/ViewPagesScreen';
import SaveJournalingScreen from '../Screens/Journaling/SaveJournalScreen';
import { createStackNavigator } from '@react-navigation/stack'

const Nav = createStackNavigator();
Expand All @@ -14,7 +16,9 @@ const HomeStackNavigator = ({navigation}) => {
<Nav.Navigator initialRouteName="Home">
<Nav.Screen name="Home" component={HomeScreen} />
<Nav.Screen name="Journaling" component={JournalingScreen} />
<Nav.Screen name="Save Journal" component={SaveJournalingScreen} />
<Nav.Screen name="View Journals" component={ViewJournalsScreen} />
<Nav.Screen name="My Journal" component={ViewPagesScreen} />
</Nav.Navigator>
)
}
Expand Down
4 changes: 2 additions & 2 deletions frontendMobile/src/Screens/HomeScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ export default function HomeScreen({navigation}) {
<Text style={s.buttonText}>View Journals</Text>
</TouchableOpacity>
</View>
<View style={s.horizontalLine} />
<View testID='Habits'>
<Text>-- Habits Go Here --</Text>
</View>

{/* Modal Components */}
<View style={s.horizontalLine} />
<JournalingChoices visible={journalChoicesVisible}
onClose={closeJournalChoices}
navigation={navigation}
Expand Down
63 changes: 63 additions & 0 deletions frontendMobile/src/Screens/Journaling/JournalingScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { useState, useEffect } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, TouchableWithoutFeedback, Keyboard } from 'react-native';
import { mainStyle } from '../../Styles/Styles';
import RandomPromptGenerator from '../../Utils/Prompts';
import JournalPage from '../../Components/JournalPage';

const s = StyleSheet.create(mainStyle);

const JournalingScreen = ({ navigation, route }) => {
const { journalType } = route.params;

const [generatedPrompt, setGeneratedPrompt] = useState('');

// User data that will be sent to the backend.
const [journalData, setJournalData] = useState({
name: journalType,
journal_type: journalType,
});
const [pageData, setPageData] = useState({
journal_id: '',
prompt: '',
entry: '',
});

const goToSubmit = () => {
const saveParams = {
journalData: journalData,
pageData: pageData,
};
navigation.navigate("Save Journal", saveParams);
};

if (journalType === "Random Prompt") {
useEffect(() => {setGeneratedPrompt(RandomPromptGenerator())}, []);
useEffect(() => {
setPageData({
...pageData,
prompt: generatedPrompt,
})
}, [generatedPrompt]);
};

return (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
<View style={s.container}>
<JournalPage
type={journalType}
prompt={generatedPrompt}
pageData={pageData}
setPageData={setPageData}
/>
<TouchableOpacity style={s.journal.submitButton}>
<Text style={s.buttonText}>New Page --&gt;</Text>
</TouchableOpacity>
<TouchableOpacity style={s.journal.submitButton} onPress={goToSubmit}>
<Text style={s.buttonText}>Submit</Text>
</TouchableOpacity>
</View>
</TouchableWithoutFeedback>
);
};

export default JournalingScreen;
Loading