Skip to content

Commit

Permalink
Multi-practice + some cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
michalparkola committed May 18, 2024
1 parent 7dac979 commit 3556d34
Show file tree
Hide file tree
Showing 12 changed files with 216 additions and 76 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ web-build/
# The following patterns were generated by expo-cli

expo-env.d.ts
# @end expo-cli
# @end expo-cli
.vercel
2 changes: 1 addition & 1 deletion app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Stack } from "expo-router";
export default function RootLayout() {
return (
<Stack>
<Stack.Screen name="index" options={{ title: "do 100 reps" }} />
<Stack.Screen name="index" options={{ title: "Do 100 reps" }} />
</Stack>
);
}
16 changes: 11 additions & 5 deletions app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from "react";
import "react-native-url-polyfill/auto";
import PracticeView from "../components/PracticeView";
import { supabase } from "./supabase";
import { Session, SupabaseClient } from "@supabase/supabase-js";
import Auth from "../components/Auth";

import { supabase } from "@/helpers/supabase";
import { Session } from "@supabase/supabase-js";
import Auth from "@/components/Auth";
import PracticeList from "@/components/PracticeList";

export default function Index() {
const [session, setSession] = React.useState<Session | null>(null);
Expand All @@ -19,5 +20,10 @@ export default function Index() {
}, []);

if (!session) return <Auth />;
else return <PracticeView />;
else
return (
<>
<PracticeList />
</>
);
}
9 changes: 9 additions & 0 deletions app/practice/[id].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import PracticeView from "@/components/PracticeView";
import { useLocalSearchParams } from "expo-router";
import { Text } from "react-native";

export default function Practice() {
const { id } = useLocalSearchParams<{ id: string }>();

return <PracticeView practiceId={id} />;
}
2 changes: 1 addition & 1 deletion components/Auth.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from "react";
import { Alert, StyleSheet, View } from "react-native";
import { supabase } from "../app/supabase";
import { supabase } from "../helpers/supabase";
import { Button, Input } from "react-native-elements";

export default function Auth() {
Expand Down
57 changes: 57 additions & 0 deletions components/PracticeGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { View, FlatList } from "react-native";
import React from "react";

interface Props {
nextRep: number;
size: number;
}

export default function PracticeGrid({ nextRep, size }: Props) {
function lightUpGrid(nextRep: number) {
let newRepsGrid = Array.from({ length: 10 }, () => Array(10).fill(false));

let repsDone = nextRep - 1;
let nextRow = 0;

while (repsDone >= 10) {
newRepsGrid[nextRow] = Array(10).fill(true);
nextRow += 1;
repsDone -= 10;
}

let nextCol = 0;
while (repsDone > 0) {
newRepsGrid[nextRow][nextCol] = true;
nextCol += 1;
repsDone -= 1;
}
return newRepsGrid;
}

const repsGrid = lightUpGrid(nextRep);

const renderRepGridItem = ({ item }: { item: Array<[boolean, string]> }) => (
<View style={{ flexDirection: "row" }}>
{item.map((isCompleted, index) => (
<View
key={index}
style={{
width: size,
height: size,
backgroundColor: isCompleted ? "green" : "gray",
margin: size >= 10 ? 1 : 0,
}}
/>
))}
</View>
);

return (
<FlatList
data={repsGrid}
keyExtractor={(item, index) => index.toString()}
renderItem={renderRepGridItem}
scrollEnabled={false}
/>
);
}
69 changes: 69 additions & 0 deletions components/PracticeList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { useState, useEffect } from "react";
import { View, Text, FlatList, Pressable } from "react-native";
import { Link } from "expo-router";
import { supabase } from "@/helpers/supabase";
import PracticeGrid from "@/components/PracticeGrid";

export default function PracticeList() {
const [practices, setPractices] = useState<any[]>([]);

useEffect(() => {
getPracticesFromSupabase();
}, []);

async function getPracticesFromSupabase() {
try {
const { data } = await supabase
.from("Practices")
.select()
.not("do100reps_title", "is", null);

if (data) {
setPractices(data);
}
} catch (error) {
console.error(error);
}
}

return (
<FlatList
style={{ marginLeft: 12, marginRight: 12, marginTop: 12 }}
data={practices}
keyExtractor={(item) => item.do100reps_title}
renderItem={({ item }) => (
<Link href={"/practice/" + item.id}>
<View
style={{
flexDirection: "row",
backgroundColor: "#fff",
borderRadius: 5,
padding: 12,
marginBottom: 12,
elevation: 5,
width: 360,
}}
>
<View style={{ marginRight: 5 }}>
<PracticeGrid nextRep={item.do100reps_count + 1} size={9} />
</View>
<View style={{ marginLeft: 10, flex: 1 }}>
<Text style={{ marginBottom: 5 }}>{item.name}</Text>
<Text
style={{
fontSize: 16,
fontWeight: "bold",
}}
>
{item.do100reps_title}
</Text>
<Text style={{ marginTop: 5 }}>
Completed reps: {item.do100reps_count}/100
</Text>
</View>
</View>
</Link>
)}
/>
);
}
107 changes: 45 additions & 62 deletions components/PracticeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,61 +9,59 @@ import {
Keyboard,
ScrollView,
} from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { supabase } from "../app/supabase";
import PracticeGrid from "@/components/PracticeGrid";
import { supabase } from "@/helpers/supabase";

export default function PracticeView() {
interface Props {
practiceId?: string;
}

export default function PracticeView({ practiceId }: Props) {
// TODO check if valid practiceId

const [isLoading, setIsLoading] = React.useState(true);
const [nextRep, setNextRep] = React.useState<number>(1);
const [nextRepText, setNextRepText] = React.useState("");
const [practice, setPractice] = React.useState<any>(null);
const [reps, setReps] = React.useState<any[]>([]);
const [repsGrid, setRepsGrid] = React.useState(
Array(10).fill(Array(10).fill(false))
);

React.useEffect(() => {
getAllFromSupabase();
getRepsFromSupabase();
}, []);

function lightUpGrid() {
console.log("LightUpGrid, nextRep = ", nextRep);
let newRepsGrid = Array.from({ length: 10 }, () => Array(10).fill(false));

let repsDone = nextRep - 1;
let nextRow = 0;

while (repsDone >= 10) {
newRepsGrid[nextRow] = Array(10).fill(true);
nextRow += 1;
repsDone -= 10;
}

let nextCol = 0;
while (repsDone > 0) {
newRepsGrid[nextRow][nextCol] = true;
nextCol += 1;
repsDone -= 1;
}
setRepsGrid(newRepsGrid);
}
async function getRepsFromSupabase() {
try {
const practicePromise = await supabase
.from("Practices")
.select()
.eq("id", practiceId);

React.useEffect(lightUpGrid, [nextRep]);
let practiceName = null;
if (practicePromise.data) {
setPractice(practicePromise.data[0]);
console.log(practice);
practiceName = practicePromise.data[0].name;
}

async function getAllFromSupabase() {
try {
const { data } = await supabase
const repsPromise = await supabase
.from("Reps")
.select()
.eq("practice", "Running")
.eq("practice", practiceName)
.order("created_at", { ascending: true });

if (data) {
setNextRep(data.length + 1);
if (repsPromise.data) {
setNextRep(repsPromise.data.length + 1);
let tmp: Array<{ repNumber: number; repText: string }> = [];
for (let rep in data) {
tmp.push({ repNumber: Number(rep) + 1, repText: data[rep].summary });
for (let rep in repsPromise.data) {
tmp.push({
repNumber: Number(rep) + 1,
repText: repsPromise.data[rep].summary,
});
}
setReps(tmp.reverse());
}

setIsLoading(false);
} catch (error) {
console.error(error);
}
Expand All @@ -73,7 +71,12 @@ export default function PracticeView() {
try {
await supabase
.from("Reps")
.insert({ summary: nextRepText, practice: "Running" });
.insert({ summary: nextRepText, practice: practice.name });

await supabase
.from("Practices")
.update({ do100reps_count: nextRep })
.eq("id", practice.id);

setReps((prevReps) => [
{ repNumber: nextRep.toString(), repText: nextRepText },
Expand All @@ -88,21 +91,7 @@ export default function PracticeView() {
}
}

const renderRepGridItem = ({ item }: { item: Array<[boolean, string]> }) => (
<View style={{ flexDirection: "row" }}>
{item.map((isCompleted, index) => (
<View
key={index}
style={{
width: 10,
height: 10,
backgroundColor: isCompleted ? "green" : "gray",
margin: 1,
}}
/>
))}
</View>
);
if (isLoading) return <Text>Loading...</Text>;

return (
<ScrollView
Expand All @@ -118,18 +107,12 @@ export default function PracticeView() {
marginBottom: 12,
}}
>
Complete 100 runs to improve my heart health
{practice.do100reps_title}
</Text>

<View style={{ flexDirection: "row" }}>
<View>
<FlatList
style={{ marginLeft: 12 }}
data={repsGrid}
keyExtractor={(item, index) => index.toString()}
renderItem={renderRepGridItem}
scrollEnabled={false}
/>
<View style={{ marginLeft: 12 }}>
<PracticeGrid nextRep={nextRep} size={10} />
</View>
<Text style={{ fontSize: 32, marginLeft: 12 }}>
Next rep {nextRep.toString()}/100
Expand Down
File renamed without changes.
7 changes: 4 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 3556d34

Please sign in to comment.