Working transition auth/clip

This commit is contained in:
Romain CLEMENT 2023-04-09 20:13:52 +02:00
parent 2c1df94e27
commit 07e4984fef
9 changed files with 132 additions and 74 deletions

View File

@ -21,44 +21,63 @@ import ClipViewLocal from './clip/ClipViewLocal';
import ClipViewRemote from './clip/ClipViewRemote';
import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import SignUp from './auth/SignUp';
import SignIn from './auth/SignIn';
import SignUp from './auth/SignUp';
import { Provider } from 'react-redux';
import store from './redux/store';
const Stack = createNativeStackNavigator();
const Tab = createMaterialBottomTabNavigator();
function Clip() {
return (
<Tab.Navigator>
<Tab.Screen name="Local" options={{ title: 'local' }}>
{(props) => <ClipViewLocal navigation={props.navigation} type={"local"} />}
</Tab.Screen>
<Tab.Screen name="Remote" options={{ title: 'remote' }}>
{(props) => <ClipViewRemote navigation={props.navigation} type={"remote"} />}
</Tab.Screen>
</Tab.Navigator>
);
}
class App extends React.Component<any, any> {
function Auth() {
return <Tab.Navigator>
<Tab.Screen component={SignIn} name="Login" options={{ title: 'Sign In' }} />
<Tab.Screen component={SignUp} name="Register" options={{ title: 'Sign Up' }} />
</Tab.Navigator>;
}
constructor(props: any) {
super(props);
this.state = {
token: "",
username: ""
}
store.subscribe(() => {
console.log("see a dispatch");
this.setState({ token: store.getState().userReducer.token})
});
}
function App(): JSX.Element {
return (
<NavigationContainer>
<Stack.Navigator>
{/*-------------------------------------------*/}
<Stack.Screen component={Auth} name="Authentification" options={{title: "Authentification"}} />
{/*-------------------------------------------*/}
<Stack.Screen component={Clip} name="Clipboards" options={{title: 'Clipboard'}}/>
{/*-------------------------------------------*/}
</Stack.Navigator>
Auth() {
return <Provider store={store}>
<Tab.Navigator>
<Tab.Screen children={() => <SignIn store={store} />} name="Login" options={{ title: 'Connexion' }} />
<Tab.Screen children={() => <SignUp store={store} />} name="Register" options={{ title: 'Créer un compte' }} />
</Tab.Navigator>
</Provider>;
}
Clip() {
return (
<Tab.Navigator>
<Tab.Screen name="Local" options={{ title: 'local' }}>
{(props) => <ClipViewLocal store={store} navigation={props.navigation} type={"local"} />}
</Tab.Screen>
<Tab.Screen name="Remote" options={{ title: 'distant' }}>
{(props) => <ClipViewRemote store={store} navigation={props.navigation} type={"remote"} />}
</Tab.Screen>
</Tab.Navigator>
);
}
render(): React.ReactNode {
console.log("render app", store.getState());
console.log("app state", this.state);
return <NavigationContainer>
<Stack.Navigator>{
this.state.token === ""
?
<Stack.Screen component={this.Auth} name="Authentication" options={{ title: "Authentification" }} />
:
<Stack.Screen component={this.Clip} name="Clipboards" options={{ title: 'Presse papiers' }} />
}</Stack.Navigator>
</NavigationContainer>
);
};
}
const styles = StyleSheet.create({

View File

@ -1,6 +1,6 @@
import React from 'react';
import { View, Text, Button, TextInput } from 'react-native';
import { setUser } from '../redux/actions';
export default class SignIn extends React.Component<any, any> {
@ -16,6 +16,15 @@ export default class SignIn extends React.Component<any, any> {
}
async signInFunction() {
const signInResponse = await fetch(
'https://notifysync.simailadjalim.fr/user?username=' + this.state.username + '&password=' + this.state.password,
{ method: 'POST' }
);
const signInJson = await signInResponse.json();
if (signInJson.status === "ok") {
console.log(this.props.store);
this.props.store.dispatch(setUser(signInJson.token, this.state.username));
} else console.log(signInJson);
}
updateUsername(event: any) {
@ -29,10 +38,10 @@ export default class SignIn extends React.Component<any, any> {
render(): React.ReactNode {
return (
<View>
<Text>Sign In</Text>
<TextInput placeholder="Pseudo" value={this.state.username} onChange={this.updateUsername}/>
<Text>Connexion</Text>
<TextInput placeholder="Nom d'utilisateur" value={this.state.username} onChange={this.updateUsername}/>
<TextInput placeholder="Mot de Passe" value={this.state.password} onChange={this.updatePassword}/>
<Button title="Sign In" onPress={this.signInFunction} />
<Button title="Se connecter" onPress={this.signInFunction} />
</View>
);
}

View File

@ -1,6 +1,7 @@
import React from 'react';
import { View, Text, Button, TextInput } from 'react-native';
import { accessibilityProps } from 'react-native-paper/lib/typescript/src/components/MaterialCommunityIcon';
import { setUser } from '../redux/actions';
export default class SignUp extends React.Component<any, any> {
@ -11,56 +12,45 @@ export default class SignUp extends React.Component<any, any> {
username: '',
password: ''
}
this.signUpFunction = this.signUpFunction.bind(this);
this.updateUsername = this.updateUsername.bind(this);
this.updatePassword = this.updatePassword.bind(this);
this.signUpFunction = this.signUpFunction.bind(this);
}
async signUpFunction() {
const signInResponse = await fetch('https://notifysync.simailadjalim.fr/user', {
method: 'PUT',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password
}),
});
const signInJson = await signInResponse.json();
if (signInJson.status == "ok"){
const loginResponse = await fetch('https://notifysync.simailadjalim.fr/user', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password
}),
});
const loginJson = await loginResponse.json();
}
const signUpResponse = await fetch(
'https://notifysync.simailadjalim.fr/user?username=' + this.state.username + '&password=' + this.state.password,
{ method: 'PUT' }
);
const signUpJson = await signUpResponse.json();
if (signUpJson.status === "ok") {
const signInResponse = await fetch(
'https://notifysync.simailadjalim.fr/user?username=' + this.state.username + '&password=' + this.state.password,
{ method: 'POST' }
);
const signInJson = await signInResponse.json();
if (signInJson.status === "ok") {
console.log(this.props.store);
this.props.store.dispatch(setUser(signInJson.token, this.state.username));
} else console.log(signInJson);
} else console.log(signUpJson);
}
updateUsername(event: any) {
this.setState({ username: event.target.value });
updateUsername(username: string) {
this.setState({ username: username });
}
updatePassword(event: any) {
this.setState({ password: event.target.value });
updatePassword(password: any) {
this.setState({ password: password });
}
render(): React.ReactNode {
return (
<View>
<Text>Sign Up</Text>
<TextInput placeholder="Pseudo" value={this.state.username} onChange={this.updateUsername} />
<TextInput placeholder="Mot de Passe" value={this.state.password} onChange={this.updatePassword} />
<Button title="Sign Up" onPress={this.signUpFunction} />
<Text>Créer un compte</Text>
<TextInput placeholder="Nom d'utilisateur" value={this.state.username} onChangeText={this.updateUsername} />
<TextInput placeholder="Mot de Passe" value={this.state.password} onChangeText={this.updatePassword} />
<Button title="S'enregistrer" onPress={this.signUpFunction} />
</View>
);
}

View File

@ -1,7 +1,6 @@
import React from 'react';
import { ScrollView, Text, Button } from 'react-native';
import ClipList from './ClipList';
import { Button } from 'react-native';
import { clearUser } from '../redux/actions';
export default abstract class AClipView extends React.Component<any, any> {
@ -12,6 +11,13 @@ export default abstract class AClipView extends React.Component<any, any> {
}
}
getSignOutBtn() {
return <Button title="Sign out" onPress={() => {
console.log("logout");
this.props.store.dispatch(clearUser());
}} />
}
abstract getClips(): any;
abstract componentDidMount(): any;

View File

@ -27,6 +27,7 @@ export default class ClipViewLocal extends AClipView {
return <ScrollView>
<Text style={{ fontWeight: 'bold', fontSize: 30, margin: 20 }}>{title}</Text>
<ClipList type={this.props.type} clips={this.state.clips} />
{this.getSignOutBtn()}
</ScrollView>;
}
}

View File

@ -27,6 +27,7 @@ export default class ClipViewRemote extends AClipView {
<Text style={{ fontWeight: 'bold', fontSize: 30, margin: 20 }}>{title}</Text>
<ClipList type={this.props.type} clips={this.state.clips} />
<Button title="Refresh" onPress={() => this.componentDidMount()} />
{this.getSignOutBtn()}
</ScrollView>;
}
}

12
src/redux/actions.tsx Normal file
View File

@ -0,0 +1,12 @@
export function setUser(token: string, username: string) {
return {
type: "auth/connect",
payload: { token, username }
};
}
export function clearUser() {
return {
type: "auth/disconnect"
};
}

12
src/redux/reducers.tsx Normal file
View File

@ -0,0 +1,12 @@
const initialState = { token: "" }
export function userReducer(state = initialState, action: any) {
switch (action.type) {
case "auth/connect":
return { ...state, token: action.payload.token, username: action.payload.username };
case "auth/disconnect":
return { ...state, token: "" };
default:
return state;
}
}

8
src/redux/store.tsx Normal file
View File

@ -0,0 +1,8 @@
import { createStore, combineReducers } from "redux";
import { userReducer } from "./reducers";
export default createStore(
combineReducers({
userReducer
})
);