Skip to content

Commit

Permalink
fix: correctly handle type on plan items
Browse files Browse the repository at this point in the history
  • Loading branch information
clentfort committed Jan 29, 2024
1 parent f07df68 commit ed01fb3
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 147 deletions.
3 changes: 2 additions & 1 deletion src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,13 @@ export interface PlanItem extends ParseObject {
exercise: ParsePointer<"Exercise", Exercise>;
finishedSets: PlanItemSet[];
history: PlanItemSetHistory[];
name?: string;
note: string;
openSets: PlanItemSet[];
plan: ParsePointer<"Plan", Plan>;
position: number;
sets: PlanItemSet[];
type: string;
type: "TEXT" | "EXERCISE";
}

interface UserExtended extends ParseObject {
Expand Down
105 changes: 12 additions & 93 deletions src/app/(app)/current-plan/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
import {
Button,
Card,
List,
ListItem,
ProgressBar,
Text,
useTheme,
} from "@ui-kitten/components";
import { Button, ProgressBar, Text } from "@ui-kitten/components";
import { router, useLocalSearchParams } from "expo-router";
import React from "react";
import { Alert, Image, View } from "react-native";
import { Alert } from "react-native";

import { PlanItem as PlanItemType } from "@/api/types";
import { PlanItem } from "@/api/types";
import useObject from "@/api/use-object";
import useObjects from "@/api/use-objects";
import useUpdateObject from "@/api/use-update-object";
import PageLayout from "@/components/page-layout";
import PlanItems from "@/components/plan-items";
import useAsyncStorage from "@/hooks/use-async-storage";
import { PartiallyResolvedPointer } from "@/parse-client/pointer";
import { space } from "@/styles";

export default function PlanScreen() {
const planId = useLocalSearchParams<{ id: string }>().id!;
Expand All @@ -43,8 +34,9 @@ export default function PlanScreen() {
return <Text>Loading</Text>;
}

const exercises = planItems.results.filter(({ type }) => type === "EXERCISE");
const done = new Set(
planItems.results
exercises
.filter((item) => item.openSets.length === 0)
.map((item) => item.objectId),
);
Expand All @@ -63,7 +55,7 @@ export default function PlanScreen() {
};

const handleEndSession = () => {
if (done.size < planItems.results.length) {
if (done.size < exercises.length) {
Alert.alert(
"Training beenden?",
`Du hast erst ${done.size} von ${planItems.results.length} Übungen absolviert. Training wirklich beenden?`,
Expand All @@ -74,6 +66,10 @@ export default function PlanScreen() {
}
};

const handleItemPress = (item: PlanItem) => {
router.push(`/current-plan/exercise/${item.objectId}`);
};

return (
<PageLayout
style={{
Expand All @@ -85,18 +81,7 @@ export default function PlanScreen() {
progress={done.size / planItems.results.length}
status="success"
/>
<List
data={planItems.results}
style={{
backgroundColor: "transparent",
gap: 0,
margin: 0,
padding: 0,
}}
renderItem={({ item }) => {
return <PlanItem item={item} />;
}}
/>
<PlanItems items={planItems.results} onItemPress={handleItemPress} />
<Button
status={done.size < planItems.results.length ? "danger" : "primary"}
onPress={handleEndSession}
Expand All @@ -106,69 +91,3 @@ export default function PlanScreen() {
</PageLayout>
);
}

interface PlanItemProps {
item: PartiallyResolvedPointer<PlanItemType, "exercise">;
}

function PlanItem({ item }: PlanItemProps) {
const theme = useTheme();
const isDone = item.openSets.length === 0;
return (
<ListItem
key={item.objectId}
style={{
paddingHorizontal: space[0],
paddingVertical: space[1],
}}
>
<Card
style={{
width: "100%",
backgroundColor: isDone ? theme["color-success-500"] : undefined,
}}
onPress={() => {
router.push(`/current-plan/exercise/${item.objectId}`);
}}
>
<View style={{ flexDirection: "row", gap: space[4] }}>
<View
style={{
backgroundColor: "white",
padding: space[1],
borderRadius: space[2],
}}
>
<Image
style={{ width: 90, height: 60 }}
source={{ uri: item.exercise.defaultImageUrl }}
/>
</View>
<View
style={{
flexGrow: 1,
gap: space[2],
}}
>
<View style={{ flex: 1, flexDirection: "row" }}>
<Text
style={{
fontWeight: "bold",
flex: 1,
fontSize: 16,
lineHeight: 18,
}}
>
{item.exercise.name}
</Text>
</View>
<Text style={{ flex: 1 }}>
{item.sets.length - item.openSets.length} / {item.sets.length}{" "}
Sets
</Text>
</View>
</View>
</Card>
</ListItem>
);
}
6 changes: 2 additions & 4 deletions src/app/(app)/current-plan/exercise/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,8 @@ const DEFAULT_PAUSE_DURATION = 60 + 40;

export default function ExercisePlanScreen() {
const planItemId = useLocalSearchParams<{ id: string }>().id!;
const [pauseDuration, setPauseDuration] = useState(20);
const [pauseStartedAt, setPauseStartedAt] = useState<null | number>(
Date.now(),
);
const [pauseDuration, setPauseDuration] = useState(0);
const [pauseStartedAt, setPauseStartedAt] = useState<null | number>(null);
const [nextPauseDuration, setNextPauseDuration] = useAsyncStorage(
"pause-duration",
DEFAULT_PAUSE_DURATION,
Expand Down
52 changes: 3 additions & 49 deletions src/app/(app)/plan/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { Button, Card, List, ListItem, Text } from "@ui-kitten/components";
import { Button, Text } from "@ui-kitten/components";
import { router, useLocalSearchParams } from "expo-router";
import React from "react";
import { Image, View } from "react-native";

import useObject from "@/api/use-object";
import useObjects from "@/api/use-objects";
import useUpdateObject from "@/api/use-update-object";
import PageLayout from "@/components/page-layout";
import PlanItems from "@/components/plan-items";
import useAsyncStorage from "@/hooks/use-async-storage";
import { space } from "@/styles";

export default function PlanScreen() {
const planId = useLocalSearchParams<{ id: string }>().id!;
Expand Down Expand Up @@ -60,52 +59,7 @@ export default function PlanScreen() {
return (
<PageLayout>
<Text category="h3">{plan.name}</Text>
<List
data={planItems.results}
style={{
backgroundColor: "transparent",
}}
renderItem={({ item }) => (
<ListItem key={item.objectId}>
<Card style={{ width: "100%" }}>
<View style={{ flexDirection: "row", gap: space[4] }}>
<View
style={{
backgroundColor: "white",
padding: space[1],
borderRadius: space[2],
}}
>
<Image
style={{ width: 90, height: 60 }}
source={{ uri: item.exercise.defaultImageUrl }}
/>
</View>
<View
style={{
flexGrow: 1,
gap: space[2],
}}
>
<View style={{ flex: 1, flexDirection: "row" }}>
<Text
style={{
fontWeight: "bold",
flex: 1,
fontSize: 16,
lineHeight: 18,
}}
>
{item.exercise.name}
</Text>
</View>
<Text style={{ flex: 1 }}>0 / {item.sets.length} Sets</Text>
</View>
</View>
</Card>
</ListItem>
)}
/>
<PlanItems items={planItems.results} />
<Button onPress={handlePlanStart}>Training starten</Button>
</PageLayout>
);
Expand Down
101 changes: 101 additions & 0 deletions src/components/plan-items.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { Card, List, ListItem, Text, useTheme } from "@ui-kitten/components";
import React from "react";
import { Image, View } from "react-native";

import { PlanItem as PlanItemType } from "@/api/types";
import { PartiallyResolvedPointer } from "@/parse-client/pointer";
import { space } from "@/styles";

interface PlanItemsProps {
items: PartiallyResolvedPointer<PlanItemType, "exercise">[];
onItemPress?: (item: PlanItemType) => void;
}

export default function PlanItems({ items, onItemPress }: PlanItemsProps) {
return (
<List
data={items}
style={{
backgroundColor: "transparent",
gap: 0,
margin: 0,
padding: 0,
}}
renderItem={({ item }) => {
return (
<ListItem
key={item.objectId}
style={{
paddingHorizontal: space[0],
paddingVertical: space[1],
}}
>
{item.type === "EXERCISE" ? (
<PlanItem item={item} onPress={onItemPress} />
) : (
<Text category="label">{item.name}</Text>
)}
</ListItem>
);
}}
/>
);
}

interface PlanItemProps {
item: PartiallyResolvedPointer<PlanItemType, "exercise">;
onPress?: (item: PlanItemType) => void;
}

function PlanItem({ item, onPress }: PlanItemProps) {
const theme = useTheme();
const isDone = item.openSets.length === 0;
return (
<Card
style={{
width: "100%",
backgroundColor: isDone ? theme["color-success-500"] : undefined,
}}
onPress={() => {
onPress?.(item);
}}
>
<View style={{ flexDirection: "row", gap: space[4] }}>
<View
style={{
backgroundColor: "white",
padding: space[1],
borderRadius: space[2],
}}
>
<Image
style={{ width: 90, height: 60 }}
source={{ uri: item.exercise?.defaultImageUrl }}
/>
</View>
<View
style={{
flexGrow: 1,
gap: space[2],
}}
>
<View style={{ flex: 1, flexDirection: "row" }}>
<Text
style={{
fontWeight: "bold",
flex: 1,
fontSize: 16,
lineHeight: 18,
}}
>
{item.exercise?.name}
</Text>
</View>
<Text style={{ flex: 1 }}>
{item.sets.length - item.openSets.length} / {item.sets.length} Sets
</Text>
</View>
</View>
</Card>
);
}

0 comments on commit ed01fb3

Please sign in to comment.