commit
6bd58278a0
@ -1,5 +1,32 @@
|
||||
import {Theme} from "@react-navigation/native";
|
||||
|
||||
export const indigoColor = "rgba(14, 14, 44, 1)";
|
||||
export const purpleColor = "rgba(74, 74, 104, 1)";
|
||||
export const darksalmonColor = "rgba(233, 150, 122, 1)";
|
||||
export const greyColor = "rgba(140, 140, 161, 1)";
|
||||
export const whiteColor = "rgba(239, 239, 253, 1)";
|
||||
export const whiteColor = "rgba(239, 239, 253, 1)";
|
||||
|
||||
|
||||
export const DefaultTheme: Theme = {
|
||||
dark: false,
|
||||
colors: {
|
||||
primary: 'rgb(0, 122, 255)',
|
||||
background: "rgba(239, 239, 253, 1)",
|
||||
card: 'rgb(255, 255, 255)',
|
||||
text: 'rgb(28, 28, 30)',
|
||||
border: 'rgb(216, 216, 216)',
|
||||
notification: 'rgb(255, 59, 48)',
|
||||
},
|
||||
};
|
||||
|
||||
export const DarkTheme: Theme = {
|
||||
dark: true,
|
||||
colors: {
|
||||
primary: 'rgb(10, 132, 255)',
|
||||
background: "rgba(140, 140, 161, 1)",
|
||||
card: 'rgb(18, 18, 18)',
|
||||
text: 'rgb(229, 229, 231)',
|
||||
border: 'rgb(39, 39, 41)',
|
||||
notification: 'rgb(255, 69, 58)',
|
||||
},
|
||||
};
|
After Width: | Height: | Size: 209 B |
After Width: | Height: | Size: 315 B |
After Width: | Height: | Size: 301 B |
@ -0,0 +1,18 @@
|
||||
|
||||
export enum ActionType {
|
||||
SET_THEME = 'SET_THEME',
|
||||
}
|
||||
|
||||
type actionFetch = {
|
||||
type: ActionType.SET_THEME;
|
||||
payload: String;
|
||||
}
|
||||
|
||||
export type Action = actionFetch;
|
||||
|
||||
export const setTheme = (theme) => {
|
||||
return {
|
||||
type: ActionType.SET_THEME,
|
||||
payload: theme,
|
||||
};
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
import {CustomJoke} from "../../model/CustomJoke";
|
||||
import {SampleJoke} from "../../model/SampleJoke";
|
||||
|
||||
export enum ActionType {
|
||||
ADD_FAVORITE = 'ADD_CUSTOM_FAVORITE',
|
||||
REMOVE_FAVORITE = "REMOVE_CUSTOM_FAVORITE"
|
||||
}
|
||||
|
||||
type actionAddFetch = {
|
||||
type: ActionType.ADD_FAVORITE;
|
||||
payload: string;
|
||||
}
|
||||
type actionRemoveFetch = {
|
||||
type: ActionType.REMOVE_FAVORITE;
|
||||
payload: string;
|
||||
}
|
||||
|
||||
export type Action = actionAddFetch | actionRemoveFetch;
|
||||
|
||||
export const addFavorite = (joke: CustomJoke | SampleJoke) => ({
|
||||
type: ActionType.ADD_FAVORITE,
|
||||
payload: joke,
|
||||
});
|
||||
|
||||
export const removeFavorite = (joke: CustomJoke | SampleJoke) => ({
|
||||
type: ActionType.REMOVE_FAVORITE,
|
||||
payload: joke,
|
||||
});
|
@ -0,0 +1,21 @@
|
||||
import {Action, ActionType} from "../actions/DarkModeAction";
|
||||
|
||||
interface State {
|
||||
theme: String
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
theme: 'dark'
|
||||
}
|
||||
|
||||
const themeReducer = (state: State = initialState, action: Action) => {
|
||||
switch (action.type) {
|
||||
case ActionType.SET_THEME:
|
||||
// @ts-ignore
|
||||
return {...state, theme: action.payload};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export default themeReducer;
|
@ -0,0 +1,26 @@
|
||||
import {Action, ActionType} from "../actions/FavoriteAction";
|
||||
import {CustomJoke} from "../../model/CustomJoke";
|
||||
import {SampleJoke} from "../../model/SampleJoke";
|
||||
|
||||
interface State {
|
||||
joke: CustomJoke | SampleJoke
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
joke: new CustomJoke('', '', '', '', '')
|
||||
}
|
||||
|
||||
const favoriteReducer = (state: State = initialState, action: Action) => {
|
||||
switch (action.type) {
|
||||
case ActionType.ADD_FAVORITE:
|
||||
// @ts-ignore
|
||||
return {...state, joke: action.payload};
|
||||
case ActionType.REMOVE_FAVORITE:
|
||||
// @ts-ignore
|
||||
return {...state, joke: action.payload};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export default favoriteReducer;
|
@ -0,0 +1,28 @@
|
||||
import { setDeleteJoke } from "../actions/CustomJoke";
|
||||
|
||||
export const deleteItem = (id: string) => {
|
||||
return async dispatch => {
|
||||
try {
|
||||
const response = await fetch(`https://iut-weather-api.azurewebsites.net/jokes/${id}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": 'application/json',
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
dispatch(setDeleteJoke(id)); // Supprimer la blague dans le store Redux
|
||||
console.log('Suppression de la blague réussie');
|
||||
} else {
|
||||
console.log('Erreur lors de la requête DELETE');
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Erreur :', error);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteCustomJoke = (jokeId) => {
|
||||
return deleteItem(jokeId)
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
// Fonction pour ajouter une blague aux favoris
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import {SampleJoke} from "../../model/SampleJoke";
|
||||
import {CustomJoke} from "../../model/CustomJoke";
|
||||
|
||||
const addFavorite = async (joke: SampleJoke | CustomJoke) => {
|
||||
try {
|
||||
let favorites: { sampleJokes: SampleJoke[], customJokes: CustomJoke[] } = await AsyncStorage.getItem('@favorites');
|
||||
if (!favorites) {
|
||||
favorites = { sampleJokes: [], customJokes: [] };
|
||||
}
|
||||
if (joke instanceof SampleJoke) {
|
||||
favorites.sampleJokes.push(joke);
|
||||
} else if (joke instanceof CustomJoke) {
|
||||
favorites.customJokes.push(joke);
|
||||
}
|
||||
await AsyncStorage.setItem('@favorites', JSON.stringify(favorites));
|
||||
} catch (error) {
|
||||
console.error('Error adding favorite:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const removeFavorite = async (jokeId: string | number) => {
|
||||
try {
|
||||
var favorites: { sampleJokes: SampleJoke[], customJokes: CustomJoke[] } = await AsyncStorage.getItem('@favorites');
|
||||
if (!favorites) {
|
||||
return;
|
||||
}
|
||||
favorites.sampleJokes = favorites.sampleJokes.filter(joke => joke.id !== jokeId);
|
||||
favorites.customJokes = favorites.customJokes.filter(joke => joke.id !== jokeId);
|
||||
await AsyncStorage.setItem('@favorites', JSON.stringify(favorites));
|
||||
} catch (error) {
|
||||
console.error('Error removing favorite:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const getFavorites = async () => {
|
||||
try {
|
||||
const favoritesString = await AsyncStorage.getItem('@favorites');
|
||||
if (favoritesString !== null) {
|
||||
return JSON.parse(favoritesString);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error getting favorites:', error);
|
||||
}
|
||||
return { sampleJokes: [], customJokes: [] };
|
||||
};
|
@ -0,0 +1,21 @@
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import {Theme} from "@react-navigation/native";
|
||||
|
||||
export const storeTheme = async (theme) => {
|
||||
try {
|
||||
const jsonValue = JSON.stringify(theme)
|
||||
await AsyncStorage.setItem('@theme', jsonValue)
|
||||
console.log("theme stored")
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
export const getTheme = async () => {
|
||||
try {
|
||||
const jsonValue = await AsyncStorage.getItem('@theme')
|
||||
return jsonValue != null ? JSON.parse(jsonValue) as Theme : null;
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
@ -1,21 +1,106 @@
|
||||
import { customJokeStub } from '../data/stub/CustomJokeStub';
|
||||
import { sampleJokeStub } from '../data/stub/SampleJokeStub';
|
||||
import JokeItems from "../components/JokeItems";
|
||||
import '../types/extension';
|
||||
import {StyleSheet, View} from "react-native";
|
||||
import {purpleColor} from "../assets/Theme";
|
||||
import {Image, SafeAreaView, StyleSheet, Text, TouchableOpacity, View} from "react-native";
|
||||
import {darksalmonColor, purpleColor, whiteColor} from "../assets/Theme";
|
||||
import {useDispatch, useSelector} from "react-redux";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {getCustomJokesList, getSampleJokesList} from "../redux/thunk/GetThunk";
|
||||
|
||||
export default function Favorites() {
|
||||
// @ts-ignore
|
||||
const sampleJokes = useSelector(state => state.sampleReducer.jokes);
|
||||
// @ts-ignore
|
||||
const customJokes = useSelector(state => state.customReducer.customJokes);
|
||||
const [joke, setJoke] = useState([])
|
||||
const dispatch = useDispatch();
|
||||
const eye = require("../assets/eye_icon.png")
|
||||
const hideEye = require("../assets/eye_off_icon.png")
|
||||
|
||||
const [showCustomJoke, setCustomJoke] = useState(false); // état local pour contrôler la visibilité de la description
|
||||
const toggleDescription = () => {
|
||||
setCustomJoke(!showCustomJoke);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if(!showCustomJoke) {
|
||||
const loadSamplesJokes = async () => {
|
||||
// @ts-ignore
|
||||
await dispatch(getSampleJokesList());
|
||||
};
|
||||
loadSamplesJokes();
|
||||
setJoke(sampleJokes)
|
||||
} else {
|
||||
const loadCustomJokes = async () => {
|
||||
// @ts-ignore
|
||||
await dispatch(getCustomJokesList());
|
||||
};
|
||||
loadCustomJokes();
|
||||
setJoke(customJokes)
|
||||
}
|
||||
}, [dispatch, customJokes, sampleJokes]);
|
||||
|
||||
export default function Catalogue() {
|
||||
const allJokes = [...customJokeStub, ...sampleJokeStub];
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<JokeItems jokes={allJokes}/>
|
||||
</View>
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View style={styles.columnContainer}>
|
||||
<Text style={styles.TextButton}>Afficher les exemples</Text>
|
||||
<TouchableOpacity style={styles.Button} onPress={toggleDescription}>
|
||||
<View style={styles.jokeTypeContainer}>
|
||||
<Image
|
||||
source={showCustomJoke ? hideEye : eye}
|
||||
style={styles.imageButton}
|
||||
/>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.container}>
|
||||
<JokeItems jokes={joke}/>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
)
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: purpleColor
|
||||
backgroundColor: purpleColor,
|
||||
flex:1,
|
||||
},
|
||||
Button:{
|
||||
borderRadius : 5,
|
||||
backgroundColor : darksalmonColor,
|
||||
height:40,
|
||||
width : 60,
|
||||
flexDirection : "row"
|
||||
},
|
||||
jokeTypeContainer :{
|
||||
display : "flex",
|
||||
flex : 1,
|
||||
flexDirection: "row",
|
||||
alignItems : "center"
|
||||
},
|
||||
imageButton : {
|
||||
margin : 10,
|
||||
width: 40,
|
||||
height:30,
|
||||
top : 5,
|
||||
alignSelf : "center",
|
||||
backgroundColor: "none",
|
||||
tintColor : whiteColor,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
TextButton : {
|
||||
fontSize: 18,
|
||||
color: whiteColor,
|
||||
textAlign: 'center',
|
||||
fontWeight: 'bold',
|
||||
margin: 10,
|
||||
},
|
||||
columnContainer: {
|
||||
marginLeft: 20,
|
||||
marginRight: 20,
|
||||
width: '90%',
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}
|
||||
});
|
@ -1,21 +1,99 @@
|
||||
import { customJokeStub } from '../data/stub/CustomJokeStub';
|
||||
import { sampleJokeStub } from '../data/stub/SampleJokeStub';
|
||||
import JokeItems from "../components/JokeItems";
|
||||
import '../types/extension';
|
||||
import {StyleSheet, View} from "react-native";
|
||||
import {purpleColor} from "../assets/Theme";
|
||||
import {Image, StyleSheet, Switch, Text, View} from "react-native";
|
||||
import {darksalmonColor, DefaultTheme, DarkTheme, greyColor, indigoColor, purpleColor, whiteColor} from "../assets/Theme";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {useTheme} from "@react-navigation/native";
|
||||
import {storeTheme} from "../redux/thunk/ThemeThunk";
|
||||
|
||||
export default function Catalogue() {
|
||||
const allJokes = [...customJokeStub, ...sampleJokeStub];
|
||||
const light_mode = require("../assets/light_mode.png")
|
||||
const dark_mode = require("../assets/dark_mode.png")
|
||||
const [isDark, setDark] = React.useState(false)
|
||||
|
||||
const toggleTheme = () => {
|
||||
setDark(previousState => {
|
||||
const theme = !previousState;
|
||||
const newTheme = theme ? DarkTheme : DefaultTheme;
|
||||
storeTheme(newTheme);
|
||||
return theme;
|
||||
});
|
||||
};
|
||||
|
||||
const styles = themeSettings();
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<JokeItems jokes={allJokes}/>
|
||||
<View style={styles.topText}>
|
||||
<Text style={styles.title}>Réglages</Text>
|
||||
<View style={styles.switchMode}>
|
||||
<View style={styles.textContainer}>
|
||||
<Image
|
||||
source={isDark? dark_mode: light_mode}
|
||||
style={styles.imageButton} />
|
||||
<Text style={styles.darkModeText}>Dark Mode</Text>
|
||||
</View>
|
||||
<Switch
|
||||
value={isDark}
|
||||
onValueChange={toggleTheme}
|
||||
style={styles.switchMode}
|
||||
trackColor={{false: darksalmonColor, true: darksalmonColor}}
|
||||
thumbColor={whiteColor} />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: purpleColor
|
||||
}
|
||||
});
|
||||
export function themeSettings() {
|
||||
const theme = useTheme();
|
||||
const colors = theme.colors;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
||||
container: {
|
||||
paddingTop: 10,
|
||||
paddingBottom: 10,
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
backgroundColor: colors.background,
|
||||
flexDirection: 'column',
|
||||
},
|
||||
topText: {
|
||||
flex: 1,
|
||||
},
|
||||
title: {
|
||||
padding: 10,
|
||||
fontSize: 20,
|
||||
color: whiteColor,
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
imageButton : {
|
||||
width: 30,
|
||||
height:30,
|
||||
alignSelf : "center",
|
||||
tintColor: darksalmonColor,
|
||||
},
|
||||
switchMode: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: indigoColor,
|
||||
padding: 20,
|
||||
margin: 10,
|
||||
},
|
||||
darkModeText: {
|
||||
color: whiteColor,
|
||||
fontSize: 20,
|
||||
marginLeft: 10,
|
||||
paddingTop: 5,
|
||||
},
|
||||
textContainer: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
}
|
||||
});
|
||||
return styles;
|
||||
}
|
Loading…
Reference in new issue