Kaynağa Gözat

timer working pretty well.

Tomi Cvetic 4 yıl önce
ebeveyn
işleme
443e6e575f

+ 224 - 22
frontend/initial-data.ts

@@ -11,7 +11,7 @@ const data: { trainings: ITraining[]; polls: any } = {
         description: "High Intensity Interval Training"
       },
       createdAt: "2020-03-25T21:13:43.284Z",
-      trainingDate: "2020-03-26T10:45:00.000Z",
+      trainingDate: "2020-03-31T09:45:00.000Z",
       location: "At home",
       registrations: [],
       attendance: 0,
@@ -31,7 +31,7 @@ const data: { trainings: ITraining[]; polls: any } = {
           },
           blocks: [
             {
-              id: "block0",
+              id: "block1",
               sequence: 0,
               title: "Lateral move with jumps",
               repetitions: 1,
@@ -44,7 +44,7 @@ const data: { trainings: ITraining[]; polls: any } = {
               rest: 25,
               blocks: [
                 {
-                  id: "block0",
+                  id: "block2",
                   duration: 40,
                   video: "/media/block0.mp4",
                   exercises: [
@@ -109,7 +109,7 @@ const data: { trainings: ITraining[]; polls: any } = {
                   ]
                 },
                 {
-                  id: "block1",
+                  id: "block3",
                   duration: 30,
                   video: "/media/block1.webm",
                   exercises: [
@@ -158,7 +158,7 @@ const data: { trainings: ITraining[]; polls: any } = {
                   ]
                 },
                 {
-                  id: "block2",
+                  id: "block4",
                   duration: 20,
                   exercises: [
                     {
@@ -194,7 +194,7 @@ const data: { trainings: ITraining[]; polls: any } = {
               ]
             },
             {
-              id: "block0",
+              id: "block5",
               sequence: 0,
               title: "Pushup with frog-jump and block jump",
               repetitions: 1,
@@ -207,7 +207,7 @@ const data: { trainings: ITraining[]; polls: any } = {
               rest: 25,
               blocks: [
                 {
-                  id: "block3",
+                  id: "block6",
                   duration: 40,
                   exercises: [
                     {
@@ -266,7 +266,7 @@ const data: { trainings: ITraining[]; polls: any } = {
                   ]
                 },
                 {
-                  id: "block4",
+                  id: "block7",
                   duration: 30,
                   exercises: [
                     {
@@ -312,7 +312,7 @@ const data: { trainings: ITraining[]; polls: any } = {
                   ]
                 },
                 {
-                  id: "block5",
+                  id: "block8",
                   duration: 20,
                   exercises: [
                     {
@@ -350,7 +350,7 @@ const data: { trainings: ITraining[]; polls: any } = {
         },
 
         {
-          id: "block1",
+          id: "block9",
           sequence: 0,
           title: "Power Sets with Kicker",
           repetitions: 2,
@@ -362,7 +362,7 @@ const data: { trainings: ITraining[]; polls: any } = {
           rest: 25,
           blocks: [
             {
-              id: "block0",
+              id: "block10",
               sequence: 0,
               title: "Block A",
               repetitions: 1,
@@ -375,7 +375,7 @@ const data: { trainings: ITraining[]; polls: any } = {
               rest: 25,
               blocks: [
                 {
-                  id: "block0",
+                  id: "block11",
                   duration: 25,
                   exercises: [
                     {
@@ -407,7 +407,7 @@ const data: { trainings: ITraining[]; polls: any } = {
                   ]
                 },
                 {
-                  id: "block1",
+                  id: "block12",
                   duration: 25,
                   exercises: [
                     {
@@ -439,7 +439,7 @@ const data: { trainings: ITraining[]; polls: any } = {
                   ]
                 },
                 {
-                  id: "block2",
+                  id: "block13",
                   duration: 10,
                   exercises: [
                     {
@@ -461,7 +461,7 @@ const data: { trainings: ITraining[]; polls: any } = {
             },
 
             {
-              id: "block1",
+              id: "block14",
               sequence: 0,
               title: "Block B",
               repetitions: 1,
@@ -474,7 +474,7 @@ const data: { trainings: ITraining[]; polls: any } = {
               rest: 25,
               blocks: [
                 {
-                  id: "block3",
+                  id: "block15",
                   duration: 25,
                   exercises: [
                     {
@@ -506,7 +506,7 @@ const data: { trainings: ITraining[]; polls: any } = {
                   ]
                 },
                 {
-                  id: "block4",
+                  id: "block16",
                   duration: 25,
                   exercises: [
                     {
@@ -525,7 +525,7 @@ const data: { trainings: ITraining[]; polls: any } = {
                   ]
                 },
                 {
-                  id: "block5",
+                  id: "block17",
                   duration: 10,
                   exercises: [
                     {
@@ -547,7 +547,7 @@ const data: { trainings: ITraining[]; polls: any } = {
             },
 
             {
-              id: "block2",
+              id: "block18",
               sequence: 0,
               title: "Block C",
               repetitions: 1,
@@ -560,7 +560,7 @@ const data: { trainings: ITraining[]; polls: any } = {
               rest: 25,
               blocks: [
                 {
-                  id: "block5",
+                  id: "block19",
                   duration: 25,
                   exercises: [
                     {
@@ -592,7 +592,7 @@ const data: { trainings: ITraining[]; polls: any } = {
                   ]
                 },
                 {
-                  id: "block5",
+                  id: "block20",
                   duration: 25,
                   exercises: [
                     {
@@ -611,7 +611,7 @@ const data: { trainings: ITraining[]; polls: any } = {
                   ]
                 },
                 {
-                  id: "block5",
+                  id: "block1",
                   duration: 10,
                   exercises: [
                     {
@@ -632,6 +632,208 @@ const data: { trainings: ITraining[]; polls: any } = {
               ]
             }
           ]
+        },
+
+        {
+          id: "block25",
+          sequence: 0,
+          title: "Leg AMRAP",
+          repetitions: 3,
+          format: {
+            id: "format0",
+            name: "AMRAP",
+            description: "As many rounds as possible"
+          },
+          rest: 25,
+          blocks: [
+            {
+              id: "block0",
+              duration: 90,
+              exercises: [
+                {
+                  id: "exercise6",
+                  name: "Leap/Jump",
+                  repetitions: 5,
+                  description: "",
+                  videos: [],
+                  pictures: [],
+                  targets: [],
+                  baseExercise: {
+                    id: "baseExercise1",
+                    name: "Mountain climber"
+                  }
+                },
+                {
+                  id: "exercise1",
+                  name: "Low 180",
+                  repetitions: 10,
+                  description: "",
+                  videos: [],
+                  pictures: [],
+                  targets: [],
+                  baseExercise: {
+                    id: "baseExercise1",
+                    name: "Plank"
+                  }
+                },
+                {
+                  id: "exercise1",
+                  name: "Ice skater",
+                  repetitions: 15,
+                  description: "",
+                  videos: [],
+                  pictures: [],
+                  targets: [],
+                  baseExercise: {
+                    id: "baseExercise1",
+                    name: "Plank"
+                  }
+                }
+              ]
+            }
+          ]
+        },
+
+        {
+          id: "block3",
+          sequence: 0,
+          title: "1 Minute Challenges",
+          repetitions: 1,
+          format: {
+            id: "format0",
+            name: "Sequence",
+            description: "Sequence of exercises"
+          },
+          rest: 25,
+          blocks: [
+            {
+              id: "block0",
+              duration: 60,
+              rest: 25,
+              exercises: [
+                {
+                  id: "exercise6",
+                  name: "Single arm burpee",
+                  repetitions: 8,
+                  description: "",
+                  videos: [],
+                  pictures: [],
+                  targets: [],
+                  baseExercise: {
+                    id: "baseExercise1",
+                    name: "Mountain climber"
+                  }
+                },
+                {
+                  id: "exercise1",
+                  name: "Single arm plank + Foot lift L/R",
+                  repetitions: 8,
+                  description: "",
+                  videos: [],
+                  pictures: [],
+                  targets: [],
+                  baseExercise: {
+                    id: "baseExercise1",
+                    name: "Plank"
+                  }
+                }
+              ]
+            },
+
+            {
+              id: "block0",
+              duration: 60,
+              rest: 25,
+              exercises: [
+                {
+                  id: "exercise6",
+                  name: "Rotation drop squat + Jack",
+                  repetitions: 8,
+                  description: "",
+                  videos: [],
+                  pictures: [],
+                  targets: [],
+                  baseExercise: {
+                    id: "baseExercise1",
+                    name: "Mountain climber"
+                  }
+                },
+                {
+                  id: "exercise1",
+                  name: "Hold squat + Step out L/R",
+                  repetitions: 8,
+                  description: "",
+                  videos: [],
+                  pictures: [],
+                  targets: [],
+                  baseExercise: {
+                    id: "baseExercise1",
+                    name: "Plank"
+                  }
+                }
+              ]
+            }
+          ]
+        },
+
+        {
+          id: "block2",
+          sequence: 0,
+          title: "Core AMRAP",
+          repetitions: 1,
+          format: {
+            id: "format0",
+            name: "AMRAP",
+            description: "As many rounds as possible"
+          },
+          rest: 25,
+          blocks: [
+            {
+              id: "block0",
+              duration: 90,
+              exercises: [
+                {
+                  id: "exercise6",
+                  name: "C-Crunch",
+                  repetitions: 10,
+                  description: "",
+                  videos: [],
+                  pictures: [],
+                  targets: [],
+                  baseExercise: {
+                    id: "baseExercise1",
+                    name: "Mountain climber"
+                  }
+                },
+                {
+                  id: "exercise1",
+                  name: "Bicycle crunch",
+                  repetitions: 10,
+                  description: "",
+                  videos: [],
+                  pictures: [],
+                  targets: [],
+                  baseExercise: {
+                    id: "baseExercise1",
+                    name: "Plank"
+                  }
+                },
+                {
+                  id: "exercise1",
+                  name: "Mountain climber",
+                  repetitions: 10,
+                  description: "",
+                  videos: [],
+                  pictures: [],
+                  targets: [],
+                  baseExercise: {
+                    id: "baseExercise1",
+                    name: "Plank"
+                  }
+                }
+              ]
+            }
+          ]
         }
       ]
     }

+ 0 - 39
frontend/pages/_app.js

@@ -1,39 +0,0 @@
-import App from 'next/app'
-import { ApolloProvider } from '@apollo/client'
-
-import Page from '../src/app/components/Page'
-import client from '../src/lib/apollo'
-import { StoreProvider } from '../src/lib/store'
-
-class MyApp extends App {
-  static async getInitialProps ({ Component, ctx }) {
-    let pageProps = {}
-
-    if (Component.getInitialProps) {
-      pageProps = await Component.getInitialProps(ctx)
-    }
-
-    // Add the query object to the pageProps
-    // https://github.com/wesbos/Advanced-React/blob/master/finished-application/frontend/pages/_app.js
-    pageProps.query = ctx.query
-    return { pageProps }
-  }
-
-  render () {
-    const { Component, pageProps } = this.props
-    console.log(client)
-    console.log(ApolloProvider)
-
-    return (
-      <StoreProvider>
-        <ApolloProvider client={client}>
-          <Page>
-            <Component {...pageProps} />
-          </Page>
-        </ApolloProvider>
-      </StoreProvider>
-    )
-  }
-}
-
-export default MyApp

+ 35 - 0
frontend/pages/_app.tsx

@@ -0,0 +1,35 @@
+import App from "next/app";
+import { ApolloProvider } from "@apollo/client";
+
+import Page from "../src/app/components/Page";
+import client from "../src/lib/apollo";
+import { StoreProvider } from "../src/lib/store";
+
+class MyApp extends App {
+  static async getInitialProps({ Component, ctx }: any) {
+    let pageProps: any = {};
+
+    if (Component.getInitialProps) {
+      pageProps = await Component.getInitialProps(ctx);
+    }
+
+    // Add the query object to the pageProps
+    // https://github.com/wesbos/Advanced-React/blob/master/finished-application/frontend/pages/_app.js
+    pageProps.query = ctx.query;
+    return { pageProps };
+  }
+
+  render() {
+    const { Component, pageProps } = this.props;
+
+    return (
+      <ApolloProvider client={client}>
+        <Page>
+          <Component {...pageProps} />
+        </Page>
+      </ApolloProvider>
+    );
+  }
+}
+
+export default MyApp;

+ 12 - 2
frontend/pages/index.tsx

@@ -15,11 +15,11 @@ const Home = () => {
         <h1>Stay in Shape with u-fit</h1>
         <p>u-fit is a high intensity interval training offered by u-blox.</p>
         <aside>
-          <div id="trainingTime">
+          <div className="info">
             <span className="caption">When</span>
             <span className="data">Tuesdays, 11:45-12:30</span>
           </div>
-          <div id="trainingEquipment">
+          <div className="info">
             <span className="caption">Equipment</span>
             <span className="data">Towel, water, optional: yoga mat</span>
           </div>
@@ -29,6 +29,16 @@ const Home = () => {
       <section id="nextTraining">
         <Training training={initialData.trainings[0]} />
       </section>
+
+      <style jsx>
+        {`
+          .info .caption {
+            display: inline-block;
+            font-weight: 900;
+            min-width: 6rem;
+          }
+        `}
+      </style>
     </>
   );
 };

+ 0 - 10
frontend/pages/login.js

@@ -1,10 +0,0 @@
-import { LoginForm } from '../src/user'
-
-const LoginPage = props => (
-  <>
-    <h1>Login</h1>
-    <LoginForm />
-  </>
-)
-
-export default LoginPage

+ 0 - 11
frontend/pages/training.js

@@ -1,11 +0,0 @@
-//import TrainingForm from "../src/training/components/trainingForm";
-//import { TrainingTypeForm } from "../components/trainingType";
-
-const Training = props => (
-  <>
-    <h1>Hey there!</h1>
-    <p>Nothing here...</p>
-  </>
-);
-
-export default Training;

+ 1 - 0
frontend/src/app/components/Header.tsx

@@ -1,4 +1,5 @@
 import Logo from "./Logo";
+import Link from "next/link";
 
 const Header = () => (
   <header>

+ 32 - 23
frontend/src/app/components/Logo.tsx

@@ -1,29 +1,38 @@
+import Link from "next/link";
+
 const Logo = () => (
-  <div id="logo">
-    <span id="circle">˙u</span>
-    <span id="text">fit</span>
+  <Link href="/">
+    <a>
+      <div id="logo">
+        <span id="circle">˙u</span>
+        <span id="text">fit</span>
+      </div>
+      <style jsx>
+        {`
+          #logo {
+            position: relative;
+            height: 60px;
+            width: 60px;
+            color: white;
+            background-color: red;
+            border-radius: 30px;
+            font-size: 40px;
+            font-weight: 900;
+            padding: 10px 0 0 15px;
+          }
 
-    <style jsx>
-      {`
-        #logo {
-          position: relative;
-          height: 60px;
-          width: 60px;
-          color: white;
-          background-color: red;
-          border-radius: 30px;
-          font-size: 40px;
-          font-weight: 900;
-          padding: 10px 0 0 15px;
-        }
+          a {
+            text-decoration: none;
+          }
 
-        #text {
-          color: black;
-          margin-left: 3px;
-        }
-      `}
-    </style>
-  </div>
+          #text {
+            color: black;
+            margin-left: 3px;
+          }
+        `}
+      </style>
+    </a>
+  </Link>
 );
 
 export default Logo;

+ 31 - 15
frontend/src/timer/components/Timer.tsx

@@ -30,7 +30,10 @@ const Timer = ({ training }: { training: ITraining }) => {
         two: [13208, 13930 - 13208],
         one: [14376, 14948 - 14376],
         go: [18219, 18735 - 18219],
-        rest: [18988, 19615 - 18988]
+        rest: [18988, 19615 - 18988],
+        ninety: [24418, 25540 - 24418],
+        sixty: [25791, 26831 - 25791],
+        thirty: [27027, 28250 - 27027]
       }
     })
   );
@@ -54,20 +57,23 @@ const Timer = ({ training }: { training: ITraining }) => {
   //console.log("aaa", time, currentExercise);
 
   useEffect(() => {
+    if (time > state.totalTime) stopTimer();
     const countdown = currentExercise
       ? currentExercise.duration + currentExercise.offset - timer.intTime + 1
       : 0;
-    if (timer.running && rosie.current) {
-      if (countdown === 5) rosie.current.play("five");
+    if (timer.running && rosie.current && !rosie.current.playing()) {
+      if (exerciseTime < 1) {
+        if (currentExercise && currentExercise.exercise !== "Rest")
+          rosie.current.play("go");
+        else rosie.current.play("rest");
+      } else if (countdown === 90) rosie.current.play("ninety");
+      else if (countdown === 60) rosie.current.play("sixty");
+      else if (countdown === 30) rosie.current.play("thirty");
+      else if (countdown === 5) rosie.current.play("five");
       else if (countdown === 4) rosie.current.play("four");
       else if (countdown === 3) rosie.current.play("three");
       else if (countdown === 2) rosie.current.play("two");
       else if (countdown === 1) rosie.current.play("one");
-      if (exerciseTime < 1) {
-        if (currentExercise && currentExercise.exercise === "Rest")
-          rosie.current.play("rest");
-        else rosie.current.play("go");
-      }
     }
   }, [time, timer.running]);
 
@@ -101,6 +107,10 @@ const Timer = ({ training }: { training: ITraining }) => {
     }
   }
 
+  const videoSrc =
+    currentExercise && currentExercise.video
+      ? currentExercise.video
+      : "/media/Pexels_Videos_2786540.mp4";
   //console.log("current state:", currentExercise, state);
 
   return (
@@ -108,13 +118,20 @@ const Timer = ({ training }: { training: ITraining }) => {
       <div>
         {/*<label htmlFor="rest">Rest</label>
         <input type="number" min="25" max="60" step="5" defaultValue="25" />*/}
-        <button onClick={back}>back</button>
+        <button onClick={back} disabled={timer.running}>
+          back
+        </button>
         <button onClick={timer.running ? stopTimer : startTimer}>
           {timer.running ? "stop" : "start"}
         </button>
-        <button onClick={forward}>forward</button>
+        <button onClick={forward} disabled={timer.running}>
+          forward
+        </button>
       </div>
       <div className="content">
+        <h1>
+          {(currentExercise && currentExercise.toplevelBlock) || "Torture"}
+        </h1>
         <Countdown
           seconds={
             currentExercise ? currentExercise.duration - exerciseTime : 0
@@ -134,11 +151,7 @@ const Timer = ({ training }: { training: ITraining }) => {
           {nextExercise ? nextExercise.exercise : "😎"}
         </div>
         <VideoPlayer
-          src={
-            currentExercise && currentExercise.video
-              ? currentExercise.video
-              : ""
-          }
+          src={videoSrc}
           getVideoHandle={(videoHandle: VideoJsPlayer) =>
             (video.current = videoHandle)
           }
@@ -171,6 +184,9 @@ const Timer = ({ training }: { training: ITraining }) => {
             grid-auto-flow: dense;
             grid-template-columns: 1fr auto;
           }
+          .content h1 {
+            grid-column: 1/3;
+          }
           .header,
           .exercise {
             grid-column: 1/2;

+ 10 - 2
frontend/src/timer/components/VideoPlayer.tsx

@@ -12,7 +12,11 @@ const VideoPlayer = ({
   const video: { current: VideoJsPlayer | undefined } = useRef();
 
   useEffect(() => {
-    const tmp = videojs(videoPlayerRef.current, { width: 320, loop: true });
+    const tmp = videojs(videoPlayerRef.current, {
+      width: 320,
+      loop: true,
+      controls: true
+    });
     getVideoHandle(tmp);
     video.current = tmp;
     return () => {
@@ -21,7 +25,11 @@ const VideoPlayer = ({
   }, []);
 
   useEffect(() => {
-    if (video.current) video.current.src(src);
+    if (video.current) {
+      const paused = video.current.paused();
+      video.current.src(src);
+      if (!paused) video.current.play();
+    }
   }, [src]);
 
   return (

+ 1 - 0
frontend/src/timer/types.ts

@@ -3,4 +3,5 @@ export interface IExerciseItem {
   duration: number;
   offset: number;
   video?: string;
+  toplevelBlock?: string;
 }

+ 9 - 3
frontend/src/timer/utils.ts

@@ -37,13 +37,18 @@ export function getPosition(exerciseList: IExerciseItem[], time: number) {
  */
 export function getExerciseList(
   blocks: IBlock[],
-  initialOffset = 0
+  initialOffset = 0,
+  toplevelBlock: undefined | string = undefined
 ): IExerciseItem[] {
   let offset = initialOffset;
   return blocks
     .map(block => {
       if (block.blocks) {
-        const subBlocks = getExerciseList(block.blocks, offset);
+        const subBlocks = getExerciseList(
+          block.blocks,
+          offset,
+          toplevelBlock || block.title
+        );
         const lastItem = subBlocks[subBlocks.length - 1];
         offset = lastItem.offset + lastItem.duration;
         if (block.rest) {
@@ -53,8 +58,8 @@ export function getExerciseList(
           } else {
             subBlocks.push({
               exercise: "Rest",
+              toplevelBlock: toplevelBlock || block.title,
               duration: block.rest,
-              video: block.video,
               offset
             });
             offset += block.rest;
@@ -72,6 +77,7 @@ export function getExerciseList(
             .join(" - "),
           duration: calculateDuration(block),
           video: block.video,
+          toplevelBlock: toplevelBlock || block.title,
           offset
         };
         offset += calculateDuration(block);

+ 10 - 3
frontend/src/training/components/Training.tsx

@@ -15,7 +15,7 @@ const Training = ({ training }: { training: ITraining }) => {
       <section>
         <h2>Program</h2>
         <Link href="/timer">
-          <a>Start Timer</a>
+          <button>Start Timer</button>
         </Link>
         {training.blocks &&
           training.blocks
@@ -32,7 +32,6 @@ const Training = ({ training }: { training: ITraining }) => {
               "information placeholder"
               "content content";
             grid-template-columns: 1fr 2fr;
-            background-color: rgba(127, 127, 127, 0.5);
             background-image: url("media/man_working_out.jpg");
             background-size: auto 400px;
             background-repeat: no-repeat;
@@ -55,11 +54,19 @@ const Training = ({ training }: { training: ITraining }) => {
           section {
             grid-area: content;
             padding: 1em 2em;
-            background: rgba(127, 0, 0, 0.2);
           }
 
           span.caption {
           }
+
+          button {
+            border: none;
+            background: ${theme.colors.darkblue};
+            color: ${theme.colors.offWhite};
+            font-weight: 900;
+            padding: 0.5rem;
+            cursor: pointer;
+          }
         `}
       </style>
     </article>

+ 13 - 8
frontend/src/training/components/TrainingMeta.tsx

@@ -4,29 +4,29 @@ import { calculateRating } from "../utils";
 const TrainingMeta = ({ training }: { training: ITraining }) => {
   return (
     <aside>
-      <div id="trainingType">
+      <div className="info">
         <span className="caption">Type: </span>
         <span className="data">{training.type.name}</span>
       </div>
-      <div id="trainingDate">
+      <div className="info">
         <span className="caption">Date: </span>
         <span className="data">
           {new Date(training.trainingDate).toLocaleString()}
         </span>
       </div>
-      <div id="trainingLocation">
+      <div className="info">
         <span className="caption">Location: </span>
         <span className="data">{training.location}</span>
       </div>
-      <div id="trainingRegistrations">
+      {/*<div className="info">
         <span className="caption">Registrations: </span>
-        <span className="data"> {training.registrations.length} </span>
+        <span className="data">{training.registrations.length} </span>
       </div>
-      <div id="trainingAttendance">
+      <div className="info">
         <span className="caption">Attendance: </span>
         <span className="data">{training.attendance}</span>
       </div>
-      <div id="trainingRatings">
+      <div className="info">
         <span className="caption">Rating: </span>
         <span className="data">
           {calculateRating(training.ratings)} [
@@ -38,7 +38,7 @@ const TrainingMeta = ({ training }: { training: ITraining }) => {
           <a href="">*</a>
         </span>
       </div>
-      <button>Register now!</button>
+          <button>Register now!</button>*/}
 
       <style jsx>{`
         aside {
@@ -48,6 +48,11 @@ const TrainingMeta = ({ training }: { training: ITraining }) => {
           padding: 0.2em 1em;
           margin: 0;
         }
+        .info .caption {
+          font-weight: 900;
+          display: inline-block;
+          min-width: 7em;
+        }
       `}</style>
     </aside>
   );

+ 4 - 10
frontend/tsconfig.json

@@ -6,11 +6,7 @@
     "moduleResolution": "Node",
     "allowSyntheticDefaultImports": true,
     "strict": true,
-    "lib": [
-      "dom",
-      "dom.iterable",
-      "esnext"
-    ],
+    "lib": ["dom", "dom.iterable", "esnext"],
     "allowJs": true,
     "skipLibCheck": true,
     "forceConsistentCasingInFileNames": true,
@@ -19,14 +15,12 @@
     "resolveJsonModule": true,
     "isolatedModules": true
   },
-  "exclude": [
-    "node_modules"
-  ],
+  "exclude": ["node_modules"],
   "include": [
     "next-env.d.ts",
     "**/*.ts",
     "**/*.tsx",
     "lib/apollo.js",
-    "pages/_app.js"
+    "pages/_app.tsx"
   ]
-}
+}