Skip to content

Commit

Permalink
groups refactor to separate components
Browse files Browse the repository at this point in the history
  • Loading branch information
lorekadam committed Jul 4, 2019
1 parent b563fab commit 1b8ff23
Show file tree
Hide file tree
Showing 16 changed files with 310 additions and 142 deletions.
4 changes: 3 additions & 1 deletion src/Navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as screens from './screens';
import DiceScreen from './screens/DiceScreen';
import TournamentScreen from './screens/TournamentScreen';
import OneFromGiven from './components/OneFromGiven';
import NewGameScreen from './screens/NewGameScreen';

const AppNavigator = createStackNavigator(
{
Expand All @@ -13,9 +14,10 @@ const AppNavigator = createStackNavigator(
[screens.DICE]: DiceScreen,
[screens.TOURNAMENT]: TournamentScreen,
[screens.ONE_FROM_GIVEN]: OneFromGiven,
[screens.NEW_GAME]: NewGameScreen,
},
{
initialRouteName: screens.HOME,
initialRouteName: screens.GROUPS,
headerMode: 'none',
},
);
Expand Down
136 changes: 13 additions & 123 deletions src/components/Groups.tsx
Original file line number Diff line number Diff line change
@@ -1,132 +1,22 @@
import React, { useState, useEffect } from 'react';
import { Button, Text } from 'react-native-paper';
import {
AsyncStorage, StyleSheet, ScrollView, View,
} from 'react-native';
import React from 'react';
import { View } from 'react-native';
import { SingleOption } from '../types';

import NumberInput from './NumberInput';
import OptionsInput from './OptionsInput';
import { Group } from '../styled/Elements';
import OptionsList from './OptionsList';
import BasicView from '../screens/BasicView';
import PillOptionsList from './PillOptionsList';

const styles = StyleSheet.create({
group: {
padding: 5,
margin: 5,
borderWidth: 1,
borderColor: 'black',
},
});

interface State {
text: string;
options: SingleOption[];
pastOptions: {[name:string]:SingleOption};
groupsAmount: number;
interface Props {
groups: SingleOption[][];
}

export default function Groups() {
const [options, setOptions] = useState<State['options']>([]);
const [pastOptions, setPastOptions] = useState<State['pastOptions']>({});
const [groupsAmount, setGroupsAmount] = useState<State['groupsAmount']>(2);
const [groups, setGroups] = useState<State['groups']>([]);

useEffect(() => {
const getPastGroupOptions = async () => {
const result = await AsyncStorage.getItem('pastGroupOptions');
if(result){
setPastOptions(JSON.parse(result));
}
};
getPastGroupOptions();
});

const addOption = async (text: SingleOption['text']) => {
setOptions([...options, { text }]);
const pastGroupOptions = await AsyncStorage.getItem('pastGroupOptions');
if (pastGroupOptions) {
const newOptionsValue = JSON.parse(pastGroupOptions);
if(!newOptionsValue[text]){
newOptionsValue[text] = { text };
await AsyncStorage.setItem('pastGroupOptions', JSON.stringify(newOptionsValue));
}
} else {
await AsyncStorage.setItem('pastGroupOptions', JSON.stringify({ [text]: { text } }));
}
};

const removeOption = (index: number) => {
setOptions(options.filter((option, i) => i !== index));
};

const removeHistoryOption = async (text: string) => {
delete pastOptions[text];
await AsyncStorage.setItem('pastGroupOptions', JSON.stringify(pastOptions));
}

const updateGroupsAmount = (number: State['groupsAmount']) => {
setGroupsAmount(number);
};

const makeGroups = () => {
const groups: State['groups'] = [];
const source = [...options];
let group = 0;
for (let i = 0; i < options.length; i++) {
const optionIndex = Math.floor(Math.random() * source.length);
if (groups[group] === undefined) {
groups[group] = [];
}
groups[group].push(source[optionIndex]);
group++;
source.splice(optionIndex, 1);
if (group === groupsAmount) {
group = 0;
}
}
setGroups(groups);
};

const clearHistory = async () => {
await AsyncStorage.setItem('pastGroupOptions', '');
setPastOptions({});
};

export default function Groups(props: Props) {
const { groups } = props;
return (
<BasicView>
<ScrollView>
<Button icon="shuffle" mode="contained" onPress={clearHistory}>
Clear history
</Button>
{Object.keys(pastOptions).length > 0 &&
<PillOptionsList onPress={addOption} onClose={removeHistoryOption} data={Object.keys(pastOptions)} />
}
<Text>Groups amount</Text>
<NumberInput
number={groupsAmount}
update={updateGroupsAmount}
disabledRemove={groupsAmount === 2}
/>
<Button
icon="shuffle"
mode="contained"
onPress={makeGroups}
disabled={options.length < groupsAmount}
>
Random
</Button>
{groups.length > 0
&& groups.map((group, i) => (
<View style={styles.group} key={i}>
<OptionsList data={group} />
</View>
))}
<OptionsInput add={addOption} />
<OptionsList data={options} remove={removeOption} />
</ScrollView>
</BasicView>
<View>
{groups.map((group, i) => (
<Group key={i}>
<OptionsList data={group} />
</Group>
))}
</View>
);
}
20 changes: 20 additions & 0 deletions src/components/GroupsAmount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { View } from 'react-native';
import { Text } from 'react-native-paper';
import NumberInput from './NumberInput';

interface Props {
number: number;
update(number: number): void;
}

export default function GroupsAmount(props: Props) {
const { number, update } = props;

return (
<View>
<Text>Ilość grup</Text>
<NumberInput number={number} update={update} disabledRemove={number === 2} />
</View>
);
}
54 changes: 54 additions & 0 deletions src/components/InputHistory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, { useState, useEffect } from 'react';
import { View, AsyncStorage } from 'react-native';
import { Button } from 'react-native-paper';
import { SingleOption } from '../types';
import PillOptionsList from './PillOptionsList';

interface State {
historyOptions: { [name: string]: SingleOption };
}

interface Props {
onPress(text: string): void;
}

export default function InputHistory(props: Props) {
const { onPress } = props;
const [historyOptions, setHistoryOptions] = useState<State['historyOptions']>({});
useEffect(() => {
const historyOptions = async () => {
const result = await AsyncStorage.getItem('historyOptions');
if (result) {
setHistoryOptions(JSON.parse(result));
}
};
historyOptions();
});

const clearHistory = async () => {
await AsyncStorage.setItem('historyOptions', '');
setHistoryOptions({});
};

const removeHistoryOption = async (text: string) => {
delete historyOptions[text];
await AsyncStorage.setItem('historyOptions', JSON.stringify(historyOptions));
};

return (
Object.keys(historyOptions).length > 0 && (
<View>
<Button icon="shuffle" mode="contained" onPress={clearHistory}>
Wyczyść historię
</Button>
{Object.keys(historyOptions).length > 0 && (
<PillOptionsList
onPress={onPress}
onClose={removeHistoryOption}
data={Object.keys(historyOptions)}
/>
)}
</View>
)
);
}
62 changes: 62 additions & 0 deletions src/components/NewGame.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React, { useState } from 'react';
import { Button } from 'react-native-paper';
import BasicView from '../screens/BasicView';
import { Row, Col } from '../styled/Grid';
import { blue, lightBlue } from '../styled/colors';
import Title from './Title';
import Groups from './Groups';

interface State {
teams: number;
time: number;
}

export default function NewGame() {
const teamsOptions: number[] = [2, 3, 4, 5, 6];
const timeOptions: { min: number; sec: number }[] = [
{ min: 1, sec: 60 },
{ min: 1.5, sec: 90 },
{ min: 2, sec: 120 },
{ min: 2.5, sec: 150 },
{ min: 3, sec: 180 },
];
const [teams, setTeams] = useState<State['teams']>(2);
const [time, setTime] = useState<State['time']>(90);
return (
<BasicView>
<Title text="Ilość drużyn" />
<Row>
{teamsOptions.map(option => (
<Col key={option}>
<Button
color={teams === option ? blue : lightBlue}
mode="contained"
onPress={() => setTeams(option)}
>
{option}
</Button>
</Col>
))}
</Row>
<Title text="Gracze" />
<Groups />
<Title text="Długość rundy (minuty)" />
<Row>
{timeOptions.map((timeOption) => {
const { min, sec } = timeOption;
return (
<Col key={min}>
<Button
color={sec === time ? blue : lightBlue}
mode="contained"
onPress={() => setTime(sec)}
>
{min}
</Button>
</Col>
);
})}
</Row>
</BasicView>
);
}
17 changes: 6 additions & 11 deletions src/components/OneFromGiven.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import React, { useState } from 'react';
import { View, FlatList, StyleSheet } from 'react-native';
import { View, FlatList } from 'react-native';
import { Checkbox, Button } from 'react-native-paper';
import { IndexKeyExtractor } from '../utils';
import { SingleCategory, Item } from '../types';
import { Col, Row, RowColumn } from '../styled/Grid';
import { FlexView, BackgroundView, PaddingView } from '../styled/Views';
import { lightBlue, dark, light, blue } from '../styled/colors';
import { Col, Row } from '../styled/Grid';
import {PaddingView } from '../styled/Views';
import { dark, blue } from '../styled/colors';
import { Text } from '../styled/Text';
import Title from './Title';
import BackButton from './BackButton';
import BasicView from '../screens/BasicView';

interface State {
Expand All @@ -31,15 +30,11 @@ export const getCategoryList = (category) => {
return require('../../assets/actors.json');
case 'Sport':
return require('../../assets/sport.json');
case 'Sitcoms':
return require('../../assets/sitcoms.json');
case 'Netflix':
return require('../../assets/netflix.json');
}
};

export default function OneFromGiven() {
const categoriesOptions = ['Movies', 'Games', 'Actors', 'Sport', 'Sitcoms', 'Netflix'];
const categoriesOptions = ['Movies', 'Games', 'Actors', 'Sport'];
const [categories, setCategories] = useState<State['categories']>({});
const [result, setResult] = useState<State['result']>(null);

Expand Down Expand Up @@ -88,7 +83,7 @@ export default function OneFromGiven() {
<View>
<Title text="Categories" />
<FlatList
numColumns={3}
numColumns={4}
data={categoriesOptions}
keyExtractor={IndexKeyExtractor}
renderItem={({ item }) => (
Expand Down
48 changes: 48 additions & 0 deletions src/components/RollGroups.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import { View } from 'react-native';
import { Button } from 'react-native-paper';
import { SingleOption } from '../types';

interface State {
groups: SingleOption[][];
}

interface Props {
options: SingleOption[];
groupsAmount: number;
setGroups(groups: SingleOption[][]): void;
}

export default function RollGroups(props: Props) {
const { options, groupsAmount, setGroups } = props;
const makeGroups = () => {
const groups: State['groups'] = [];
const source = [...options];
let group = 0;
for (let i = 0; i < options.length; i++) {
const optionIndex = Math.floor(Math.random() * source.length);
if (groups[group] === undefined) {
groups[group] = [];
}
groups[group].push(source[optionIndex]);
group++;
source.splice(optionIndex, 1);
if (group === groupsAmount) {
group = 0;
}
}
setGroups(groups);
};
return (
<View>
<Button
icon="shuffle"
mode="contained"
onPress={makeGroups}
disabled={options.length < groupsAmount}
>
Random
</Button>
</View>
);
}
Loading

0 comments on commit 1b8ff23

Please sign in to comment.