mirror of
https://github.com/lemeow125/Reactnative-notesapp.git
synced 2024-11-17 06:29:27 +08:00
Merge pull request #24 from lemeow125/feature/initial_frontend
Feature/initial frontend
This commit is contained in:
commit
ce4e6735e4
26 changed files with 6270 additions and 636 deletions
15
App.tsx
15
App.tsx
|
@ -7,14 +7,21 @@ import DrawerScreenSettings from "./src/Components/Drawer/DrawerScreenSettings/D
|
||||||
|
|
||||||
import Home from "./src/Routes/Home/Home";
|
import Home from "./src/Routes/Home/Home";
|
||||||
import UserInfo from "./src/Routes/UserInfo/UserInfo";
|
import UserInfo from "./src/Routes/UserInfo/UserInfo";
|
||||||
import AddNote from "./src/Routes/AddNote/AddNote";
|
import NewNote from "./src/Routes/NewNote/NewNote";
|
||||||
import Login from "./src/Routes/Login/Login";
|
import Login from "./src/Routes/Login/Login";
|
||||||
import Register from "./src/Routes/Register/Register";
|
import Register from "./src/Routes/Register/Register";
|
||||||
|
import { Provider } from "react-redux";
|
||||||
|
import Store from "./src/Features/Redux/Store/Store";
|
||||||
|
import { QueryClient, QueryClientProvider } from "react-query";
|
||||||
|
import EditNote from "./src/Routes/EditNote/EditNote";
|
||||||
|
|
||||||
const Drawer = createDrawerNavigator();
|
const Drawer = createDrawerNavigator();
|
||||||
|
const queryClient = new QueryClient();
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
return (
|
return (
|
||||||
|
<Provider store={Store}>
|
||||||
|
<QueryClientProvider client={queryClient}>
|
||||||
<NavigationContainer>
|
<NavigationContainer>
|
||||||
<Drawer.Navigator
|
<Drawer.Navigator
|
||||||
initialRouteName="Home"
|
initialRouteName="Home"
|
||||||
|
@ -22,11 +29,15 @@ export default function App() {
|
||||||
screenOptions={DrawerScreenSettings}
|
screenOptions={DrawerScreenSettings}
|
||||||
>
|
>
|
||||||
<Drawer.Screen name="Home" component={Home} />
|
<Drawer.Screen name="Home" component={Home} />
|
||||||
<Drawer.Screen name="Add Note" component={AddNote} />
|
<Drawer.Screen name="New Note" component={NewNote} />
|
||||||
<Drawer.Screen name="User Info" component={UserInfo} />
|
<Drawer.Screen name="User Info" component={UserInfo} />
|
||||||
<Drawer.Screen name="Login" component={Login} />
|
<Drawer.Screen name="Login" component={Login} />
|
||||||
<Drawer.Screen name="Register" component={Register} />
|
<Drawer.Screen name="Register" component={Register} />
|
||||||
|
<Drawer.Screen name="LogOut" component={Register} />
|
||||||
|
<Drawer.Screen name="EditNote" component={EditNote} />
|
||||||
</Drawer.Navigator>
|
</Drawer.Navigator>
|
||||||
</NavigationContainer>
|
</NavigationContainer>
|
||||||
|
</QueryClientProvider>
|
||||||
|
</Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
5236
package-lock.json
generated
5236
package-lock.json
generated
File diff suppressed because it is too large
Load diff
24
package.json
24
package.json
|
@ -9,21 +9,37 @@
|
||||||
"web": "expo start --web"
|
"web": "expo start --web"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@expo/webpack-config": "^18.0.1",
|
||||||
|
"@react-native-async-storage/async-storage": "1.17.11",
|
||||||
"@react-navigation/drawer": "^6.6.2",
|
"@react-navigation/drawer": "^6.6.2",
|
||||||
"@react-navigation/native": "^6.1.6",
|
"@react-navigation/native": "^6.1.6",
|
||||||
|
"@react-navigation/native-stack": "^6.9.12",
|
||||||
|
"@react-navigation/stack": "^6.3.16",
|
||||||
|
"@reduxjs/toolkit": "^1.9.3",
|
||||||
|
"axios": "^1.3.4",
|
||||||
"expo": "~48.0.5",
|
"expo": "~48.0.5",
|
||||||
|
"expo-linear-gradient": "~12.1.2",
|
||||||
"expo-status-bar": "~1.4.4",
|
"expo-status-bar": "~1.4.4",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-native": "0.71.3",
|
"react-dom": "18.2.0",
|
||||||
|
"react-native": "0.71.6",
|
||||||
|
"react-native-gesture-handler": "~2.9.0",
|
||||||
|
"react-native-paper": "^5.4.0",
|
||||||
|
"react-native-pell-rich-editor": "^1.8.8",
|
||||||
|
"react-native-reanimated": "~2.14.4",
|
||||||
"react-native-safe-area-context": "4.5.0",
|
"react-native-safe-area-context": "4.5.0",
|
||||||
"react-native-screens": "~3.20.0",
|
"react-native-screens": "~3.20.0",
|
||||||
"react-native-gesture-handler": "~2.9.0",
|
"react-native-svg": "13.4.0",
|
||||||
"react-native-reanimated": "~2.14.4",
|
"react-native-webview": "11.26.0",
|
||||||
"react-native-svg": "13.4.0"
|
"react-native-web": "~0.18.10",
|
||||||
|
"react-query": "^3.39.3",
|
||||||
|
"react-redux": "^8.0.5",
|
||||||
|
"redux": "^4.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.0",
|
"@babel/core": "^7.20.0",
|
||||||
"@types/react": "~18.0.14",
|
"@types/react": "~18.0.14",
|
||||||
|
"@types/react-native": "^0.71.5",
|
||||||
"typescript": "^4.9.4"
|
"typescript": "^4.9.4"
|
||||||
},
|
},
|
||||||
"private": true
|
"private": true
|
||||||
|
|
142
src/Components/Api/Api.tsx
Normal file
142
src/Components/Api/Api.tsx
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
import axios from "axios";
|
||||||
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||||
|
import {
|
||||||
|
ActivationParams,
|
||||||
|
UpdateNoteParams,
|
||||||
|
AddNoteParams,
|
||||||
|
LoginParams,
|
||||||
|
RegistrationParams,
|
||||||
|
} from "../../Interfaces/Interfaces";
|
||||||
|
|
||||||
|
// Note APIs
|
||||||
|
|
||||||
|
const instance = axios.create({
|
||||||
|
baseURL: "https://keannu126.pythonanywhere.com",
|
||||||
|
});
|
||||||
|
|
||||||
|
export async function GetNotes() {
|
||||||
|
const token = JSON.parse(await AsyncStorage.getItem("token") || "{}");
|
||||||
|
return instance
|
||||||
|
.get("/api/v1/notes/", {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Token " + token,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
return response.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GetPublicNotes() {
|
||||||
|
return instance.get("/api/v1/public_notes/").then((response) => {
|
||||||
|
return response.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GetNote(id: number) {
|
||||||
|
const token = JSON.parse(await AsyncStorage.getItem("token") || "{}");
|
||||||
|
return instance
|
||||||
|
.get("/api/v1/notes/" + id + "/", {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Token " + token,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
return response.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function UpdateNote(note: UpdateNoteParams) {
|
||||||
|
const token = JSON.parse(await AsyncStorage.getItem("token") || "{}");
|
||||||
|
return instance
|
||||||
|
.patch("/api/v1/notes/" + note.id + "/", note, {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Token " + token,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
return response.data;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
return error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function AddNote(note: AddNoteParams) {
|
||||||
|
const token = JSON.parse(await AsyncStorage.getItem("token") || "{}");
|
||||||
|
return instance
|
||||||
|
.post("/api/v1/notes/", note, {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Token " + token,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
return response.data;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
return error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function DeleteNote(id: number) {
|
||||||
|
const token = JSON.parse(await AsyncStorage.getItem("token") || "{}");
|
||||||
|
return instance
|
||||||
|
.delete("/api/v1/notes/" + id + "/", {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Token " + token,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
return error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// User APIs
|
||||||
|
|
||||||
|
export function UserRegister(register: RegistrationParams) {
|
||||||
|
return instance
|
||||||
|
.post("/api/v1/accounts/users/", register)
|
||||||
|
.then(async (response) => {
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function UserLogin(user: LoginParams) {
|
||||||
|
return instance
|
||||||
|
.post("/api/v1/accounts/token/login/", user)
|
||||||
|
.then(async (response) => {
|
||||||
|
AsyncStorage.setItem("token", JSON.stringify(response.data.auth_token));
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log("Login Failed: " + error);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function UserInfo() {
|
||||||
|
const token = JSON.parse(await AsyncStorage.getItem("token") || "{}");
|
||||||
|
return instance
|
||||||
|
.get("/api/v1/accounts/users/me/", {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Token " + token,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
return response.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function UserActivate(activation: ActivationParams) {
|
||||||
|
return instance
|
||||||
|
.post("/api/v1/accounts/users/activation/", activation)
|
||||||
|
.then(async (response) => {
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
|
@ -2,12 +2,14 @@ import * as React from "react";
|
||||||
import { View } from "react-native";
|
import { View } from "react-native";
|
||||||
import styles from "../../styles";
|
import styles from "../../styles";
|
||||||
|
|
||||||
|
|
||||||
export interface props {
|
export interface props {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Background(props: props) {
|
export default function Background(props: props) {
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<View style={styles.background}>
|
<View style={styles.background}>
|
||||||
<View style={{ margin: 8 }} />
|
<View style={{ margin: 8 }} />
|
||||||
{props.children}
|
{props.children}
|
||||||
|
|
|
@ -13,10 +13,21 @@ import LoginIcon from "../../../Icons/LoginIcon/LoginIcon";
|
||||||
import SignupIcon from "../../../Icons/SignupIcon/SignupIcon";
|
import SignupIcon from "../../../Icons/SignupIcon/SignupIcon";
|
||||||
import UserIcon from "../../../Icons/UserIcon/UserIcon";
|
import UserIcon from "../../../Icons/UserIcon/UserIcon";
|
||||||
import AppIcon from "../../../Icons/AppIcon/AppIcon";
|
import AppIcon from "../../../Icons/AppIcon/AppIcon";
|
||||||
|
import LogoutIcon from "../../../Icons/LogoutIcon/LogoutIcon";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import { RootState } from "../../../../Features/Redux/Store/Store";
|
||||||
|
import { Toggle_Login } from "../../../../Features/Redux/Slices/LoginSlice/LoginSlice";
|
||||||
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||||
|
|
||||||
export default function CustomDrawerContent(props: {}) {
|
export default function CustomDrawerContent(props: {}) {
|
||||||
const navigation = useNavigation<RootDrawerParamList>();
|
const navigation = useNavigation<RootDrawerParamList>();
|
||||||
|
const dispatch = useDispatch();
|
||||||
const width = 224;
|
const width = 224;
|
||||||
|
const logged_in = useSelector((state: RootState) => state.logged_in.value);
|
||||||
|
const logged_in_user = useSelector(
|
||||||
|
(state: RootState) => state.logged_in_user.value
|
||||||
|
);
|
||||||
|
if (logged_in) {
|
||||||
return (
|
return (
|
||||||
<DrawerContentScrollView {...props}>
|
<DrawerContentScrollView {...props}>
|
||||||
<View
|
<View
|
||||||
|
@ -30,6 +41,9 @@ export default function CustomDrawerContent(props: {}) {
|
||||||
Clip Notes
|
Clip Notes
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 16 } }}>
|
||||||
|
Logged in as {logged_in_user.username}
|
||||||
|
</Text>
|
||||||
<ButtonAlignLeft
|
<ButtonAlignLeft
|
||||||
color="Blue"
|
color="Blue"
|
||||||
width={width}
|
width={width}
|
||||||
|
@ -38,30 +52,23 @@ export default function CustomDrawerContent(props: {}) {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<HomeIcon size={32} color="white" />
|
<HomeIcon size={32} color="white" />
|
||||||
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}>Home</Text>
|
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}>
|
||||||
|
Home
|
||||||
|
</Text>
|
||||||
</ButtonAlignLeft>
|
</ButtonAlignLeft>
|
||||||
|
|
||||||
<ButtonAlignLeft
|
<ButtonAlignLeft
|
||||||
color="Green"
|
color="Green"
|
||||||
width={width}
|
width={width}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
navigation.navigate("Add Note");
|
navigation.navigate("New Note");
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<AddIcon size={32} color="white" />
|
<AddIcon size={32} color="white" />
|
||||||
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}>
|
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}>
|
||||||
Add Note
|
New Note
|
||||||
</Text>
|
</Text>
|
||||||
</ButtonAlignLeft>
|
</ButtonAlignLeft>
|
||||||
<ButtonAlignLeft
|
|
||||||
color="Green"
|
|
||||||
width={width}
|
|
||||||
onPress={() => {
|
|
||||||
navigation.navigate("Login");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<LoginIcon size={32} color="white" />
|
|
||||||
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}>Login</Text>
|
|
||||||
</ButtonAlignLeft>
|
|
||||||
<ButtonAlignLeft
|
<ButtonAlignLeft
|
||||||
color="Yellow"
|
color="Yellow"
|
||||||
width={width}
|
width={width}
|
||||||
|
@ -74,6 +81,60 @@ export default function CustomDrawerContent(props: {}) {
|
||||||
User Info
|
User Info
|
||||||
</Text>
|
</Text>
|
||||||
</ButtonAlignLeft>
|
</ButtonAlignLeft>
|
||||||
|
<ButtonAlignLeft
|
||||||
|
color="Red"
|
||||||
|
width={width}
|
||||||
|
onPress={() => {
|
||||||
|
dispatch(Toggle_Login());
|
||||||
|
AsyncStorage.removeItem("token");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<LogoutIcon size={32} color="white" />
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}>
|
||||||
|
Log Out
|
||||||
|
</Text>
|
||||||
|
</ButtonAlignLeft>
|
||||||
|
</DrawerContentScrollView>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<DrawerContentScrollView {...props}>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
...styles.flex_row,
|
||||||
|
...{ justifyContent: "center" },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AppIcon size={32} color="white" />
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}>
|
||||||
|
Clip Notes
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<ButtonAlignLeft
|
||||||
|
color="Blue"
|
||||||
|
width={width}
|
||||||
|
onPress={() => {
|
||||||
|
navigation.navigate("Home");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<HomeIcon size={32} color="white" />
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}>
|
||||||
|
Home
|
||||||
|
</Text>
|
||||||
|
</ButtonAlignLeft>
|
||||||
|
<ButtonAlignLeft
|
||||||
|
color="Green"
|
||||||
|
width={width}
|
||||||
|
onPress={() => {
|
||||||
|
navigation.navigate("Login");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<LoginIcon size={32} color="white" />
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}>
|
||||||
|
Login
|
||||||
|
</Text>
|
||||||
|
</ButtonAlignLeft>
|
||||||
<ButtonAlignLeft
|
<ButtonAlignLeft
|
||||||
color="Yellow"
|
color="Yellow"
|
||||||
width={width}
|
width={width}
|
||||||
|
@ -89,3 +150,4 @@ export default function CustomDrawerContent(props: {}) {
|
||||||
</DrawerContentScrollView>
|
</DrawerContentScrollView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { View, Image, Text } from "react-native";
|
import { View, Image, Text } from "react-native";
|
||||||
import type { DrawerNavigationOptions } from "@react-navigation/drawer";
|
import type { DrawerNavigationOptions } from "@react-navigation/drawer";
|
||||||
import AppIcon from "../../Icons/AppIcon/AppIcon";
|
import AppIcon from "../../Icons/AppIcon/AppIcon";
|
||||||
|
import PreviousSessionChecker from "../../PreviousSessionChecker/PreviousSessionChecker";
|
||||||
const DrawerScreenSettings: DrawerNavigationOptions = {
|
const DrawerScreenSettings: DrawerNavigationOptions = {
|
||||||
headerTitleStyle: { color: "white", fontSize: 26 },
|
headerTitleStyle: { color: "white", fontSize: 26 },
|
||||||
unmountOnBlur: true,
|
unmountOnBlur: true,
|
||||||
|
@ -18,6 +19,7 @@ const DrawerScreenSettings: DrawerNavigationOptions = {
|
||||||
<View
|
<View
|
||||||
style={{ flexDirection: "row", marginRight: 16, alignItems: "center" }}
|
style={{ flexDirection: "row", marginRight: 16, alignItems: "center" }}
|
||||||
>
|
>
|
||||||
|
<PreviousSessionChecker />
|
||||||
<AppIcon size={32} color="white" />
|
<AppIcon size={32} color="white" />
|
||||||
</View>
|
</View>
|
||||||
),
|
),
|
||||||
|
|
25
src/Components/Icons/LogoutIcon/LogoutIcon.tsx
Normal file
25
src/Components/Icons/LogoutIcon/LogoutIcon.tsx
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { IconProps } from "../../../Interfaces/Interfaces";
|
||||||
|
|
||||||
|
import { Svg, Path } from "react-native-svg";
|
||||||
|
|
||||||
|
export default function LogoutIcon(props: IconProps) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Svg
|
||||||
|
width={props.size}
|
||||||
|
height={props.size}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth="2"
|
||||||
|
stroke={props.color}
|
||||||
|
fill="none"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
>
|
||||||
|
<Path stroke="none" d="M0 0h24v24H0z" fill="none"></Path>
|
||||||
|
<Path d="M14 8v-2a2 2 0 0 0 -2 -2h-7a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h7a2 2 0 0 0 2 -2v-2"></Path>
|
||||||
|
<Path d="M7 12h14l-3 -3m0 6l3 -3"></Path>
|
||||||
|
</Svg>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
63
src/Components/Note/Note.tsx
Normal file
63
src/Components/Note/Note.tsx
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { View, Text, TextInput, ScrollView } from "react-native";
|
||||||
|
import styles from "../../styles";
|
||||||
|
import { NoteProps, RootDrawerParamList } from "../../Interfaces/Interfaces";
|
||||||
|
import ButtonCentered from "../Buttons/ButtonCentered/ButtonCentered";
|
||||||
|
import { useQueryClient, useMutation } from "react-query";
|
||||||
|
import { DeleteNote } from "../Api/Api";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
export default function Note(props: NoteProps) {
|
||||||
|
const navigation = useNavigation<RootDrawerParamList>();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const mutation = useMutation({
|
||||||
|
mutationFn: DeleteNote,
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries("notes");
|
||||||
|
queryClient.invalidateQueries("public_notes");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<View style={styles.addnotecont}>
|
||||||
|
<View style={styles.tle}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.title}
|
||||||
|
value={props.title}
|
||||||
|
maxLength={20}
|
||||||
|
editable={false}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={styles.typehere}>
|
||||||
|
<ScrollView style={styles.typeinput} nestedScrollEnabled={true}>
|
||||||
|
<Text style={styles.typeinput}>{props.content}</Text>
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
<View style={styles.flex_row}>
|
||||||
|
<ButtonCentered
|
||||||
|
color={"Red"}
|
||||||
|
onPress={() => {
|
||||||
|
console.log("Deleted note id " + props.id);
|
||||||
|
mutation.mutate(props.id);
|
||||||
|
}}
|
||||||
|
width={64}
|
||||||
|
>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 16 } }}>
|
||||||
|
Delete Note
|
||||||
|
</Text>
|
||||||
|
</ButtonCentered>
|
||||||
|
<ButtonCentered
|
||||||
|
color={"Yellow"}
|
||||||
|
onPress={() => {
|
||||||
|
navigation.navigate("EditNote", { noteId: props.id });
|
||||||
|
console.log("Editing note id " + props.id);
|
||||||
|
}}
|
||||||
|
width={64}
|
||||||
|
>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 16 } }}>
|
||||||
|
Edit Note
|
||||||
|
</Text>
|
||||||
|
</ButtonCentered>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
90
src/Components/Notes/Notes.tsx
Normal file
90
src/Components/Notes/Notes.tsx
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { View, Text, TouchableOpacity, ScrollView } from "react-native";
|
||||||
|
import { useQuery } from "react-query";
|
||||||
|
import { GetNotes } from "../Api/Api";
|
||||||
|
import styles from "../../styles";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { RootState } from "../../Features/Redux/Store/Store";
|
||||||
|
import { NoteProps, RootDrawerParamList } from "../../Interfaces/Interfaces";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import Note from "../Note/Note";
|
||||||
|
|
||||||
|
export default function Notes() {
|
||||||
|
const navigation = useNavigation<RootDrawerParamList>();
|
||||||
|
const {
|
||||||
|
data: notes,
|
||||||
|
isLoading,
|
||||||
|
error,
|
||||||
|
} = useQuery("notes", GetNotes, { retry: 0 });
|
||||||
|
const logged_in = useSelector((state: RootState) => state.logged_in.value);
|
||||||
|
if (isLoading) {
|
||||||
|
return (
|
||||||
|
<Text style={{ ...styles.no, ...{ textAlign: "center" } }}>
|
||||||
|
Loading notes...
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
} else if (!logged_in && error) {
|
||||||
|
return (
|
||||||
|
<Text style={{ ...styles.no, ...{ textAlign: "center" } }}>
|
||||||
|
Please login to use Clip Notes
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
} else if (error) {
|
||||||
|
return (
|
||||||
|
<Text style={{ ...styles.no, ...{ textAlign: "center", color: "red" } }}>
|
||||||
|
Error contacting Notes server
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
} else if (notes.length === 0) {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text style={{ ...styles.no, ...{ textAlign: "center" } }}>
|
||||||
|
No notes exist yet. Create one!
|
||||||
|
</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
...styles.homecont,
|
||||||
|
...{ display: "flex", alignSelf: "center" },
|
||||||
|
}}
|
||||||
|
onPress={() => {
|
||||||
|
navigation.navigate("New Note");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={styles.newnote}>+</Text>
|
||||||
|
<Text style={styles.no}>New note...</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<ScrollView contentContainerStyle={{ justifyContent: "center" }}>
|
||||||
|
{notes.map((note: NoteProps, index: number) => {
|
||||||
|
return (
|
||||||
|
<Note
|
||||||
|
id={note.id}
|
||||||
|
key={index}
|
||||||
|
title={note.title}
|
||||||
|
content={note.content}
|
||||||
|
date_created={note.date_created}
|
||||||
|
owner={note.owner}
|
||||||
|
public={note.public}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
...styles.homecont,
|
||||||
|
...{ display: "flex", alignSelf: "center" },
|
||||||
|
}}
|
||||||
|
onPress={() => {
|
||||||
|
navigation.navigate("New Note");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={styles.newnote}>+</Text>
|
||||||
|
<Text style={styles.no}>New note...</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<View style={{ margin: 16 }} />
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { View, Text, TextInput, ScrollView } from "react-native";
|
||||||
|
import { useEffect, useCallback } from "react";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import { UserInfo } from "../Api/Api";
|
||||||
|
import { Toggle_Login } from "../../Features/Redux/Slices/LoginSlice/LoginSlice";
|
||||||
|
import { SetUser } from "../../Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice";
|
||||||
|
import { set_checked } from "../../Features/Redux/Slices/OldSession/OldSessionSlice";
|
||||||
|
import { RootState } from "../../Features/Redux/Store/Store";
|
||||||
|
export default function PreviousSessionChecker() {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const logged_in = useSelector((state: RootState) => state.logged_in.value);
|
||||||
|
// Function to check for previous login session
|
||||||
|
const check = useCallback(async () => {
|
||||||
|
if (await UserInfo()) {
|
||||||
|
if (logged_in !== true) {
|
||||||
|
console.log("Previous session found. Restoring");
|
||||||
|
await dispatch(Toggle_Login());
|
||||||
|
await dispatch(SetUser(await UserInfo()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("No old session found");
|
||||||
|
localStorage.removeItem("token");
|
||||||
|
}
|
||||||
|
await dispatch(set_checked());
|
||||||
|
}, [dispatch, logged_in]);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!logged_in) {
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
}, [check, logged_in]);
|
||||||
|
return <View />;
|
||||||
|
}
|
24
src/Components/PublicNote/PublicNote.tsx
Normal file
24
src/Components/PublicNote/PublicNote.tsx
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { View, Text, TextInput, ScrollView } from "react-native";
|
||||||
|
import styles from "../../styles";
|
||||||
|
import { NoteProps } from "../../Interfaces/Interfaces";
|
||||||
|
|
||||||
|
export default function PublicNote(props: NoteProps) {
|
||||||
|
return (
|
||||||
|
<View style={styles.addnotecont}>
|
||||||
|
<View style={styles.tle}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.title}
|
||||||
|
value={props.title}
|
||||||
|
maxLength={20}
|
||||||
|
editable={false}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={styles.typehere}>
|
||||||
|
<ScrollView style={styles.typeinput} nestedScrollEnabled={true}>
|
||||||
|
<Text style={styles.typeinput}>{props.content}</Text>
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
56
src/Components/PublicNotes/Notes.tsx
Normal file
56
src/Components/PublicNotes/Notes.tsx
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { View, Text, TouchableOpacity, ScrollView } from "react-native";
|
||||||
|
import { useQuery } from "react-query";
|
||||||
|
import { GetNotes, GetPublicNotes } from "../Api/Api";
|
||||||
|
import styles from "../../styles";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { RootState } from "../../Features/Redux/Store/Store";
|
||||||
|
import { NoteProps, RootDrawerParamList } from "../../Interfaces/Interfaces";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import Note from "../Note/Note";
|
||||||
|
import PublicNote from "../PublicNote/PublicNote";
|
||||||
|
|
||||||
|
export default function PublicNotes() {
|
||||||
|
const navigation = useNavigation<RootDrawerParamList>();
|
||||||
|
const {
|
||||||
|
data: notes,
|
||||||
|
isLoading,
|
||||||
|
error,
|
||||||
|
} = useQuery("public_notes", GetPublicNotes, { retry: 0 });
|
||||||
|
if (isLoading) {
|
||||||
|
return (
|
||||||
|
<Text style={{ ...styles.no, ...{ textAlign: "center" } }}>
|
||||||
|
Loading public notes...
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
} else if (error) {
|
||||||
|
return (
|
||||||
|
<Text style={{ ...styles.no, ...{ textAlign: "center", color: "red" } }}>
|
||||||
|
Error contacting Notes server
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
} else if (notes.length === 0) {
|
||||||
|
return (
|
||||||
|
<Text style={{ ...styles.no, ...{ textAlign: "center" } }}>
|
||||||
|
There are no public notes...
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<ScrollView contentContainerStyle={{ justifyContent: "center" }}>
|
||||||
|
{notes.map((note: NoteProps, index: number) => {
|
||||||
|
return (
|
||||||
|
<PublicNote
|
||||||
|
id={note.id}
|
||||||
|
key={index}
|
||||||
|
title={note.title}
|
||||||
|
content={note.content}
|
||||||
|
date_created={note.date_created}
|
||||||
|
owner={note.owner}
|
||||||
|
public={note.public}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
export const LoggedInUserSlice = createSlice({
|
||||||
|
name: "Login",
|
||||||
|
initialState: {
|
||||||
|
value: {
|
||||||
|
email: "",
|
||||||
|
id: 0,
|
||||||
|
username: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
SetUser: (state, action) => {
|
||||||
|
state.value = {
|
||||||
|
email: action.payload.email,
|
||||||
|
id: action.payload.id,
|
||||||
|
username: action.payload.username,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
UnsetUser: (state) => {
|
||||||
|
state.value = {
|
||||||
|
email: "",
|
||||||
|
id: 0,
|
||||||
|
username: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Action creators are generated for each case reducer function
|
||||||
|
export const { SetUser, UnsetUser } = LoggedInUserSlice.actions;
|
||||||
|
|
||||||
|
export default LoggedInUserSlice.reducer;
|
18
src/Features/Redux/Slices/LoginSlice/LoginSlice.tsx
Normal file
18
src/Features/Redux/Slices/LoginSlice/LoginSlice.tsx
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
export const LoginSlice = createSlice({
|
||||||
|
name: "Login",
|
||||||
|
initialState: {
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
Toggle_Login: (state) => {
|
||||||
|
state.value = !state.value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Action creators are generated for each case reducer function
|
||||||
|
export const { Toggle_Login } = LoginSlice.actions;
|
||||||
|
|
||||||
|
export default LoginSlice.reducer;
|
17
src/Features/Redux/Slices/OldSession/OldSessionSlice.tsx
Normal file
17
src/Features/Redux/Slices/OldSession/OldSessionSlice.tsx
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
export const OldSessionSlice = createSlice({
|
||||||
|
name: "old_session_checked",
|
||||||
|
initialState: {
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
set_checked: (state) => {
|
||||||
|
state.value = !state.value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { set_checked } = OldSessionSlice.actions;
|
||||||
|
|
||||||
|
export default OldSessionSlice.reducer;
|
18
src/Features/Redux/Store/Store.tsx
Normal file
18
src/Features/Redux/Store/Store.tsx
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { configureStore } from "@reduxjs/toolkit";
|
||||||
|
import LoginReducer from "../Slices/LoginSlice/LoginSlice";
|
||||||
|
import LoggedInUserReucer from "../Slices/LoggedInUserSlice/LoggedInUserSlice";
|
||||||
|
import OldSessionReducer from "../Slices/OldSession/OldSessionSlice";
|
||||||
|
|
||||||
|
const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
logged_in: LoginReducer,
|
||||||
|
logged_in_user: LoggedInUserReucer,
|
||||||
|
old_session_checked: OldSessionReducer,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default store;
|
||||||
|
|
||||||
|
// Infer the `RootState` and `AppDispatch` types from the store itself
|
||||||
|
export type RootState = ReturnType<typeof store.getState>;
|
||||||
|
export type AppDispatch = typeof store.dispatch;
|
|
@ -6,3 +6,65 @@ export interface IconProps {
|
||||||
export interface RootDrawerParamList {
|
export interface RootDrawerParamList {
|
||||||
navigate: any;
|
navigate: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Redux Interfaces
|
||||||
|
export interface LoginState {
|
||||||
|
Login: { logged_in: boolean };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LoggedInUserState {
|
||||||
|
LoggedInUser: {
|
||||||
|
value: {
|
||||||
|
email: string;
|
||||||
|
id: number;
|
||||||
|
username: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Component Props Interfaces
|
||||||
|
|
||||||
|
export interface NoteProps {
|
||||||
|
title: string;
|
||||||
|
content: string;
|
||||||
|
id: number;
|
||||||
|
date_created: Date;
|
||||||
|
owner: string;
|
||||||
|
public: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IconProps {
|
||||||
|
size: number;
|
||||||
|
color: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// API Interfaces
|
||||||
|
|
||||||
|
export interface RegistrationParams {
|
||||||
|
email: string;
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LoginParams {
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ActivationParams {
|
||||||
|
uid: string;
|
||||||
|
token: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AddNoteParams {
|
||||||
|
title: string;
|
||||||
|
content: string;
|
||||||
|
public: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateNoteParams {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
content: string;
|
||||||
|
public: boolean;
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
import * as React from 'react';
|
|
||||||
import {View, Text} from 'react-native';
|
|
||||||
import styles from '../../styles';
|
|
||||||
import Background from '../../Components/Background/Background';
|
|
||||||
|
|
||||||
export default function AddNote() {
|
|
||||||
return (
|
|
||||||
<Background>
|
|
||||||
<Text style={{...styles.text_white, ...{fontSize: 32}}}>Add Note</Text>
|
|
||||||
</Background>
|
|
||||||
);
|
|
||||||
}
|
|
135
src/Routes/EditNote/EditNote.tsx
Normal file
135
src/Routes/EditNote/EditNote.tsx
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { View, Text, TextInput, Switch } from "react-native";
|
||||||
|
import styles from "../../styles";
|
||||||
|
import Background from "../../Components/Background/Background";
|
||||||
|
import { SafeAreaView } from "react-native-safe-area-context";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { TouchableOpacity } from "react-native";
|
||||||
|
import { RootDrawerParamList } from "../../Interfaces/Interfaces";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import { useMutation, useQuery, useQueryClient } from "react-query";
|
||||||
|
import { AddNote, GetNote, UpdateNote } from "../../Components/Api/Api";
|
||||||
|
|
||||||
|
export default function EditNote({ navigation, route }: any) {
|
||||||
|
const { noteId } = route.params;
|
||||||
|
const [note, setNote] = useState({
|
||||||
|
title: "",
|
||||||
|
content: "",
|
||||||
|
public: false,
|
||||||
|
});
|
||||||
|
async function retrieve() {
|
||||||
|
let a = await GetNote(noteId);
|
||||||
|
setNote(a);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
const { data, isLoading, error } = useQuery("note", retrieve, {
|
||||||
|
retry: 0,
|
||||||
|
});
|
||||||
|
useEffect(() => {
|
||||||
|
setNote(data);
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const mutation = useMutation({
|
||||||
|
mutationFn: UpdateNote,
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries("notes");
|
||||||
|
queryClient.invalidateQueries("public_notes");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<Background>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}>
|
||||||
|
Error retrieving specific note
|
||||||
|
</Text>
|
||||||
|
</Background>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (isLoading) {
|
||||||
|
return (
|
||||||
|
<Background>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}>
|
||||||
|
Loading note...
|
||||||
|
</Text>
|
||||||
|
</Background>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data && note) {
|
||||||
|
return (
|
||||||
|
<Background>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}>
|
||||||
|
Edit Note
|
||||||
|
</Text>
|
||||||
|
<View style={styles.addnotecont}>
|
||||||
|
<View style={styles.tle}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.title}
|
||||||
|
placeholder="Title"
|
||||||
|
placeholderTextColor="white"
|
||||||
|
value={note.title}
|
||||||
|
onChangeText={(text) => {
|
||||||
|
setNote({ ...note, title: text });
|
||||||
|
}}
|
||||||
|
maxLength={20}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={styles.typehere}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.typeinput}
|
||||||
|
placeholder="Type here...."
|
||||||
|
placeholderTextColor="white"
|
||||||
|
value={note.content}
|
||||||
|
multiline={true}
|
||||||
|
onChangeText={async (text) => {
|
||||||
|
await setNote({ ...note, content: text });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
marginLeft: 16,
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Switch
|
||||||
|
onValueChange={() => setNote({ ...note, public: !note.public })}
|
||||||
|
value={note.public}
|
||||||
|
/>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 16 } }}>
|
||||||
|
Public?
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.savebtn}
|
||||||
|
onPress={async () => {
|
||||||
|
try {
|
||||||
|
await mutation.mutate({
|
||||||
|
title: note.title,
|
||||||
|
content: note.content,
|
||||||
|
public: note.public,
|
||||||
|
id: noteId,
|
||||||
|
});
|
||||||
|
navigation.navigate("Home");
|
||||||
|
} catch (error) {}
|
||||||
|
console.log(note.content);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={styles.savenote}>SAVE</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.cancelbtn}
|
||||||
|
onPress={() => {
|
||||||
|
navigation.navigate("Home");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={styles.cancel}>CANCEL</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</Background>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,25 +1,52 @@
|
||||||
import * as React from 'react';
|
import * as React from "react";
|
||||||
import {View, Text} from 'react-native';
|
import { View, Text } from "react-native";
|
||||||
import styles from '../../styles';
|
import styles from "../../styles";
|
||||||
import Background from '../../Components/Background/Background';
|
import Background from "../../Components/Background/Background";
|
||||||
import AppIcon from '../../Components/Icons/AppIcon/AppIcon';
|
import Notes from "../../Components/Notes/Notes";
|
||||||
|
import { Switch } from "react-native-gesture-handler";
|
||||||
|
import { useState } from "react";
|
||||||
|
import PublicNotes from "../../Components/PublicNotes/Notes";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
const [switchLabel, setLabel] = useState("Viewing public notes");
|
||||||
|
const [togglePublic, setToggled] = useState(true);
|
||||||
|
function Preview() {
|
||||||
|
if (togglePublic) {
|
||||||
|
return <PublicNotes />;
|
||||||
|
} else {
|
||||||
|
return <Notes />;
|
||||||
|
}
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Background>
|
<Background>
|
||||||
<View
|
<Text style={{ ...styles.text_white, ...{ fontSize: 25 } }}>
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
}}>
|
|
||||||
<AppIcon size={64} color="white" />
|
|
||||||
<Text style={{...styles.text_white, ...{fontSize: 32}}}>
|
|
||||||
Clip Notes
|
Clip Notes
|
||||||
</Text>
|
</Text>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
marginLeft: 16,
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Switch
|
||||||
|
onValueChange={() => {
|
||||||
|
setToggled(!togglePublic);
|
||||||
|
if (togglePublic) {
|
||||||
|
setLabel("Viewing own notes");
|
||||||
|
} else {
|
||||||
|
setLabel("Viewing public notes");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
value={togglePublic}
|
||||||
|
/>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 16 } }}>
|
||||||
|
{switchLabel}
|
||||||
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={{margin: 16}} />
|
<Preview />
|
||||||
</Background>
|
</Background>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,100 @@
|
||||||
import * as React from 'react';
|
import * as React from "react";
|
||||||
import {View, Text} from 'react-native';
|
import { View, Text, TextInput } from "react-native";
|
||||||
import styles from '../../styles';
|
import styles from "../../styles";
|
||||||
import Background from '../../Components/Background/Background';
|
import Background from "../../Components/Background/Background";
|
||||||
|
import {
|
||||||
|
SafeAreaView,
|
||||||
|
NativeSyntheticEvent,
|
||||||
|
TextInputChangeEventData,
|
||||||
|
} from "react-native";
|
||||||
|
import { StatusBar } from "expo-status-bar";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { TouchableOpacity } from "react-native";
|
||||||
|
import {
|
||||||
|
NavigationHelpersContext,
|
||||||
|
useNavigation,
|
||||||
|
} from "@react-navigation/native";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import { SetUser } from "../../Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice";
|
||||||
|
import { Toggle_Login } from "../../Features/Redux/Slices/LoginSlice/LoginSlice";
|
||||||
|
import { UserInfo, UserLogin } from "../../Components/Api/Api";
|
||||||
|
import { RootDrawerParamList } from "../../Interfaces/Interfaces";
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
|
const navigation = useNavigation<RootDrawerParamList>();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const [user, setUser] = useState({
|
||||||
|
username: "",
|
||||||
|
password: "",
|
||||||
|
});
|
||||||
|
const [error, setError] = useState("");
|
||||||
return (
|
return (
|
||||||
<Background>
|
<Background>
|
||||||
<Text style={{...styles.text_white, ...{fontSize: 32}}}>Login</Text>
|
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}></Text>
|
||||||
|
<SafeAreaView>
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text style={styles.loginlabel}>Login to Clip Notes</Text>
|
||||||
|
<StatusBar style="auto" />
|
||||||
|
<View style={styles.inputView}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.TextInput}
|
||||||
|
placeholder="Username"
|
||||||
|
placeholderTextColor="white"
|
||||||
|
value={user.username}
|
||||||
|
maxLength={20}
|
||||||
|
onChange={(
|
||||||
|
e: NativeSyntheticEvent<TextInputChangeEventData>
|
||||||
|
): void => {
|
||||||
|
setUser({ ...user, username: e.nativeEvent.text });
|
||||||
|
console.log(user.username);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.inputView}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.TextInput}
|
||||||
|
placeholder="Password"
|
||||||
|
placeholderTextColor="white"
|
||||||
|
secureTextEntry={true}
|
||||||
|
value={user.password}
|
||||||
|
onChange={(
|
||||||
|
e: NativeSyntheticEvent<TextInputChangeEventData>
|
||||||
|
): void => {
|
||||||
|
setUser({ ...user, password: e.nativeEvent.text });
|
||||||
|
console.log(user.password);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={async () => {
|
||||||
|
setUser({
|
||||||
|
username: "",
|
||||||
|
password: "",
|
||||||
|
});
|
||||||
|
if (await UserLogin(user)) {
|
||||||
|
await dispatch(Toggle_Login());
|
||||||
|
await dispatch(SetUser(await UserInfo()));
|
||||||
|
navigation.navigate("Home");
|
||||||
|
} else {
|
||||||
|
setError("Invalid Login");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
style={styles.loginBtn}
|
||||||
|
>
|
||||||
|
<Text style={styles.loginText}>LOGIN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.text_small_red}>{error}</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
navigation.navigate("Register");
|
||||||
|
}}
|
||||||
|
style={styles.registerbtn}
|
||||||
|
>
|
||||||
|
<Text style={styles.registertext}>REGISTER</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</SafeAreaView>
|
||||||
</Background>
|
</Background>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
107
src/Routes/NewNote/NewNote.tsx
Normal file
107
src/Routes/NewNote/NewNote.tsx
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { View, Text, TextInput, Switch } from "react-native";
|
||||||
|
import styles from "../../styles";
|
||||||
|
import Background from "../../Components/Background/Background";
|
||||||
|
import { SafeAreaView } from "react-native-safe-area-context";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { TouchableOpacity } from "react-native";
|
||||||
|
import { RootDrawerParamList } from "../../Interfaces/Interfaces";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import { useMutation, useQueryClient } from "react-query";
|
||||||
|
import { AddNote } from "../../Components/Api/Api";
|
||||||
|
|
||||||
|
export default function NewNote() {
|
||||||
|
const [note, setNote] = useState({
|
||||||
|
title: "",
|
||||||
|
content: "",
|
||||||
|
public: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const navigation = useNavigation<RootDrawerParamList>();
|
||||||
|
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const mutation = useMutation({
|
||||||
|
mutationFn: AddNote,
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries("notes");
|
||||||
|
queryClient.invalidateQueries("public_notes");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Background>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}>
|
||||||
|
New Note
|
||||||
|
</Text>
|
||||||
|
<SafeAreaView>
|
||||||
|
<View style={styles.addnotecont}>
|
||||||
|
<View style={styles.tle}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.title}
|
||||||
|
placeholder="Title"
|
||||||
|
placeholderTextColor="white"
|
||||||
|
value={note.title}
|
||||||
|
onChangeText={(text) => {
|
||||||
|
setNote({ ...note, title: text });
|
||||||
|
}}
|
||||||
|
maxLength={20}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={styles.typehere}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.typeinput}
|
||||||
|
placeholder="Type here...."
|
||||||
|
placeholderTextColor="white"
|
||||||
|
value={note.content}
|
||||||
|
multiline={true}
|
||||||
|
onChangeText={async (text) => {
|
||||||
|
await setNote({ ...note, content: text });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
marginLeft: 16,
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Switch
|
||||||
|
onValueChange={() => setNote({ ...note, public: !note.public })}
|
||||||
|
value={note.public}
|
||||||
|
/>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 16 } }}>
|
||||||
|
Public?
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.savebtn}
|
||||||
|
onPress={async () => {
|
||||||
|
try {
|
||||||
|
await mutation.mutate({
|
||||||
|
title: note.title,
|
||||||
|
content: note.content,
|
||||||
|
public: note.public,
|
||||||
|
});
|
||||||
|
navigation.navigate("Home");
|
||||||
|
} catch (error) {}
|
||||||
|
console.log(note.content);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={styles.savenote}>SAVE</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.cancelbtn}
|
||||||
|
onPress={() => {
|
||||||
|
navigation.navigate("Home");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={styles.cancel}>CANCEL</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</SafeAreaView>
|
||||||
|
</Background>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,12 +1,73 @@
|
||||||
import * as React from 'react';
|
import * as React from "react";
|
||||||
import {View, Text} from 'react-native';
|
import { View, Text, TextInput } from "react-native";
|
||||||
import styles from '../../styles';
|
import styles from "../../styles";
|
||||||
import Background from '../../Components/Background/Background';
|
import Background from "../../Components/Background/Background";
|
||||||
|
import { SafeAreaView } from "react-native-safe-area-context";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { TouchableOpacity } from "react-native";
|
||||||
|
import { UserRegister } from "../../Components/Api/Api";
|
||||||
|
|
||||||
export default function Register() {
|
export default function Register() {
|
||||||
|
const [username, setUsername] = useState("");
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [password, setPassword] = useState("");
|
||||||
|
const [feedback, setFeedback] = useState("");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Background>
|
<Background>
|
||||||
<Text style={{...styles.text_white, ...{fontSize: 32}}}>Register</Text>
|
<Text style={{ ...styles.text_white, ...{ fontSize: 32 } }}></Text>
|
||||||
|
<SafeAreaView>
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text style={styles.loginlabel}>Create an Account</Text>
|
||||||
|
<View style={styles.inputView}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.TextInput}
|
||||||
|
placeholder="Email"
|
||||||
|
placeholderTextColor="white"
|
||||||
|
onChangeText={setEmail}
|
||||||
|
value={email}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={styles.inputView}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.TextInput}
|
||||||
|
placeholder="Username"
|
||||||
|
placeholderTextColor="white"
|
||||||
|
onChangeText={setUsername}
|
||||||
|
value={username}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={styles.inputView}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.TextInput}
|
||||||
|
placeholder="Password"
|
||||||
|
placeholderTextColor="white"
|
||||||
|
secureTextEntry={true}
|
||||||
|
onChangeText={setPassword}
|
||||||
|
value={password}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={async () => {
|
||||||
|
setUsername("");
|
||||||
|
setPassword("");
|
||||||
|
setEmail("");
|
||||||
|
console.log("heh");
|
||||||
|
if (await UserRegister({ username, email, password })) {
|
||||||
|
setFeedback(
|
||||||
|
"Registration success. Please check your email address for activation"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
setFeedback("Invalid credentials specified");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
style={styles.registerbtn}
|
||||||
|
>
|
||||||
|
<Text style={styles.registertext}>REGISTER</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.registertext}>{feedback}</Text>
|
||||||
|
</View>
|
||||||
|
</SafeAreaView>
|
||||||
</Background>
|
</Background>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,53 @@
|
||||||
import * as React from 'react';
|
import * as React from "react";
|
||||||
import {View, Text} from 'react-native';
|
import { View, Text } from "react-native";
|
||||||
import styles from '../../styles';
|
import styles from "../../styles";
|
||||||
import Background from '../../Components/Background/Background';
|
import Background from "../../Components/Background/Background";
|
||||||
|
import { SafeAreaView } from "react-native-safe-area-context";
|
||||||
|
import { UserInfo } from "../../Components/Api/Api";
|
||||||
|
import { useQuery } from "react-query";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { RootState } from "../../Features/Redux/Store/Store";
|
||||||
|
|
||||||
export default function UserInfo() {
|
export default function UserPage() {
|
||||||
|
const { data, isLoading, error } = useQuery("user", UserInfo, {
|
||||||
|
retry: 0,
|
||||||
|
onSuccess: (data) => console.log(data),
|
||||||
|
});
|
||||||
|
const logged_in = useSelector((state: RootState) => state.logged_in.value);
|
||||||
|
if (isLoading && !error) {
|
||||||
|
return (
|
||||||
|
<View style={styles.background}>
|
||||||
|
<View style={styles.addnotecont}>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 25 } }}>
|
||||||
|
Loading...
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
} else if (error) {
|
||||||
|
return (
|
||||||
|
<View style={styles.background}>
|
||||||
|
<View style={styles.addnotecont}>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 25 } }}>
|
||||||
|
An error has occured
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Background>
|
<Background>
|
||||||
<Text style={{...styles.text_white, ...{fontSize: 32}}}>UserInfo</Text>
|
<View style={styles.addnotecont}>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 25 } }}>
|
||||||
|
Username: {data.username}
|
||||||
|
</Text>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 25 } }}>
|
||||||
|
Email: {data.email}
|
||||||
|
</Text>
|
||||||
|
<Text style={{ ...styles.text_white, ...{ fontSize: 25 } }}>
|
||||||
|
User ID: {data.id}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
</Background>
|
</Background>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
283
src/styles.tsx
283
src/styles.tsx
|
@ -1,34 +1,281 @@
|
||||||
import {StyleSheet} from 'react-native';
|
import { StyleSheet } from "react-native";
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
background: {
|
background: {
|
||||||
backgroundColor: '#002d4c',
|
height: "100%",
|
||||||
height: '100%',
|
width: "100%",
|
||||||
width: '100%',
|
backgroundColor: "#002d4d",
|
||||||
|
position: "absolute",
|
||||||
},
|
},
|
||||||
text_white: {
|
text_white: {
|
||||||
color: 'white',
|
color: "white",
|
||||||
fontWeight: 'bold',
|
fontWeight: "bold",
|
||||||
textAlign: 'center',
|
textAlign: "center",
|
||||||
},
|
},
|
||||||
button_generic: {
|
button_generic: {
|
||||||
justifyContent: 'center',
|
justifyContent: "center",
|
||||||
alignSelf: 'center',
|
alignSelf: "center",
|
||||||
alignItems: 'center',
|
alignItems: "center",
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
flexDirection: 'row',
|
flexDirection: "row",
|
||||||
margin: 8,
|
margin: 8,
|
||||||
padding: 8,
|
padding: 8,
|
||||||
borderRadius: 16,
|
borderRadius: 16,
|
||||||
},
|
},
|
||||||
flex_row: {
|
flex_row: {
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
flexDirection: 'row',
|
flexDirection: "row",
|
||||||
alignItems: 'center',
|
alignItems: "center",
|
||||||
},
|
},
|
||||||
flex_column: {
|
flex_column: {
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
flexDirection: 'column',
|
flexDirection: "column",
|
||||||
alignItems: 'center',
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
height: 40,
|
||||||
|
margin: 12,
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
|
||||||
|
inputView: {
|
||||||
|
backgroundColor: "black",
|
||||||
|
borderRadius: 30,
|
||||||
|
width: "70%",
|
||||||
|
height: 45,
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
TextInput: {
|
||||||
|
color: "white",
|
||||||
|
height: 50,
|
||||||
|
flex: 1,
|
||||||
|
padding: 10,
|
||||||
|
marginLeft: 5,
|
||||||
|
},
|
||||||
|
forgot_button: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "white",
|
||||||
|
height: 30,
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
loginBtn: {
|
||||||
|
width: "50%",
|
||||||
|
borderRadius: 25,
|
||||||
|
height: 50,
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
backgroundColor: "lightgreen",
|
||||||
|
},
|
||||||
|
registerbtn: {
|
||||||
|
width: "80%",
|
||||||
|
borderRadius: 25,
|
||||||
|
height: 50,
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginTop: 40,
|
||||||
|
backgroundColor: "orange",
|
||||||
|
},
|
||||||
|
loginText: {
|
||||||
|
color: "white",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 20,
|
||||||
|
},
|
||||||
|
registertext: {
|
||||||
|
color: "white",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 20,
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
marginTop: 30,
|
||||||
|
marginLeft: 22,
|
||||||
|
height: 500,
|
||||||
|
width: 350,
|
||||||
|
borderRadius: 25,
|
||||||
|
backgroundColor: "#0087e4",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
loginlabel: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 25,
|
||||||
|
marginBottom: 30,
|
||||||
|
color: "white",
|
||||||
|
},
|
||||||
|
box: {
|
||||||
|
width: "100%",
|
||||||
|
height: 200,
|
||||||
|
},
|
||||||
|
userinfocont: {
|
||||||
|
marginTop: 10,
|
||||||
|
marginLeft: 50,
|
||||||
|
height: 80,
|
||||||
|
width: 300,
|
||||||
|
borderRadius: 25,
|
||||||
|
backgroundColor: "orange",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
userlabel: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 25,
|
||||||
|
marginBottom: 10,
|
||||||
|
color: "white",
|
||||||
|
},
|
||||||
|
addnote: {
|
||||||
|
marginLeft: 180,
|
||||||
|
width: "10%",
|
||||||
|
borderRadius: 25,
|
||||||
|
height: 30,
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
backgroundColor: "lightgreen",
|
||||||
|
},
|
||||||
|
addtext: {
|
||||||
|
fontSize: 20,
|
||||||
|
color: "white",
|
||||||
|
},
|
||||||
|
addnotescont: {
|
||||||
|
marginTop: 20,
|
||||||
|
marginLeft: 20,
|
||||||
|
height: 200,
|
||||||
|
width: 350,
|
||||||
|
backgroundColor: "blue",
|
||||||
|
alignItems: "flex-start",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
no: {
|
||||||
|
fontSize: 20,
|
||||||
|
color: "white",
|
||||||
|
marginTop: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
typehere: {
|
||||||
|
backgroundColor: "black",
|
||||||
|
borderRadius: 10,
|
||||||
|
width: "75%",
|
||||||
|
height: 300,
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
typeinput: {
|
||||||
|
color: "white",
|
||||||
|
marginBottom: 16,
|
||||||
|
marginLeft: 5,
|
||||||
|
minHeight: 128,
|
||||||
|
maxHeight: 768,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
color: "white",
|
||||||
|
flex: 1,
|
||||||
|
marginLeft: 5,
|
||||||
|
},
|
||||||
|
tle: {
|
||||||
|
backgroundColor: "black",
|
||||||
|
borderRadius: 10,
|
||||||
|
width: "80%",
|
||||||
|
height: 40,
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
addnotecont: {
|
||||||
|
marginTop: 30,
|
||||||
|
marginLeft: 22,
|
||||||
|
paddingBottom: 30,
|
||||||
|
minHeight: 500,
|
||||||
|
width: 350,
|
||||||
|
borderRadius: 25,
|
||||||
|
backgroundColor: "#001018",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
savebtn: {
|
||||||
|
width: "40%",
|
||||||
|
borderRadius: 25,
|
||||||
|
height: 40,
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
backgroundColor: "green",
|
||||||
|
},
|
||||||
|
cancelbtn: {
|
||||||
|
width: "40%",
|
||||||
|
borderRadius: 25,
|
||||||
|
height: 40,
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
backgroundColor: "green",
|
||||||
|
},
|
||||||
|
savenote: {
|
||||||
|
color: "white",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 20,
|
||||||
|
},
|
||||||
|
cancel: {
|
||||||
|
color: "white",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 20,
|
||||||
|
},
|
||||||
|
homecont: {
|
||||||
|
marginTop: 30,
|
||||||
|
height: 150,
|
||||||
|
width: 350,
|
||||||
|
borderRadius: 25,
|
||||||
|
backgroundColor: "#7cb9e8",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
newnote: {
|
||||||
|
color: "white",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 50,
|
||||||
|
},
|
||||||
|
//
|
||||||
|
form: {
|
||||||
|
flex: 1,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
inputRow: {
|
||||||
|
width: "60%",
|
||||||
|
height: 50,
|
||||||
|
marginTop: 50,
|
||||||
|
marginLeft: 10,
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
marginBottom: 5,
|
||||||
|
marginLeft: 5,
|
||||||
|
fontSize: 20,
|
||||||
|
color: "white",
|
||||||
|
},
|
||||||
|
disabledInput: {
|
||||||
|
backgroundColor: "white",
|
||||||
|
borderRadius: 10,
|
||||||
|
},
|
||||||
|
editButton: {
|
||||||
|
backgroundColor: "green",
|
||||||
|
width: "20%",
|
||||||
|
borderRadius: 25,
|
||||||
|
height: 40,
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginTop: 20,
|
||||||
|
marginLeft: 20,
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
color: "white",
|
||||||
|
},
|
||||||
|
inputUser: {
|
||||||
|
marginLeft: 10,
|
||||||
|
height: 40,
|
||||||
|
width: "100%",
|
||||||
|
color: "black",
|
||||||
|
backgroundColor: "white",
|
||||||
|
borderRadius: 10,
|
||||||
|
},
|
||||||
|
text_small_red: {
|
||||||
|
color: "#bc231e",
|
||||||
|
fontSize: 10,
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "center",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue