Quellcode durchsuchen

should finally get database to work...

Tomi Cvetic vor 5 Jahren
Ursprung
Commit
c12fb1e8fe

Datei-Diff unterdrückt, da er zu groß ist
+ 449 - 195
backend/database/generated/prisma-client/index.ts


+ 406 - 183
backend/database/generated/prisma-client/prisma-schema.ts

@@ -6,6 +6,10 @@ export const typeDefs = /* GraphQL */ `type AggregateBlock {
   count: Int!
 }
 
+type AggregateBlockInstance {
+  count: Int!
+}
+
 type AggregateComment {
   count: Int!
 }
@@ -48,17 +52,15 @@ type BatchPayload {
 
 type Block {
   id: ID!
-  sequence: Int!
   title: String!
   description: String
   videos: [String!]!
   pictures: [String!]!
   duration: Int
-  rounds: Int
   format: Format!
   rest: Int
   tracks(where: TrackWhereInput, orderBy: TrackOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Track!]
-  blocks(where: BlockWhereInput, orderBy: BlockOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Block!]
+  blocks(where: BlockInstanceWhereInput, orderBy: BlockInstanceOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [BlockInstance!]
   exercises(where: ExerciseInstanceWhereInput, orderBy: ExerciseInstanceOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [ExerciseInstance!]
 }
 
@@ -70,23 +72,21 @@ type BlockConnection {
 
 input BlockCreateInput {
   id: ID
-  sequence: Int!
   title: String!
   description: String
   videos: BlockCreatevideosInput
   pictures: BlockCreatepicturesInput
   duration: Int
-  rounds: Int
   format: FormatCreateOneInput!
   rest: Int
   tracks: TrackCreateManyInput
-  blocks: BlockCreateManyInput
+  blocks: BlockInstanceCreateManyWithoutBlockInput
   exercises: ExerciseInstanceCreateManyInput
 }
 
-input BlockCreateManyInput {
-  create: [BlockCreateInput!]
-  connect: [BlockWhereUniqueInput!]
+input BlockCreateOneWithoutBlocksInput {
+  create: BlockCreateWithoutBlocksInput
+  connect: BlockWhereUniqueInput
 }
 
 input BlockCreatepicturesInput {
@@ -97,41 +97,87 @@ input BlockCreatevideosInput {
   set: [String!]
 }
 
+input BlockCreateWithoutBlocksInput {
+  id: ID
+  title: String!
+  description: String
+  videos: BlockCreatevideosInput
+  pictures: BlockCreatepicturesInput
+  duration: Int
+  format: FormatCreateOneInput!
+  rest: Int
+  tracks: TrackCreateManyInput
+  exercises: ExerciseInstanceCreateManyInput
+}
+
 type BlockEdge {
   node: Block!
   cursor: String!
 }
 
-enum BlockOrderByInput {
+type BlockInstance {
+  id: ID!
+  block: Block!
+  order: Int!
+  rounds: Int
+  variation: String
+}
+
+type BlockInstanceConnection {
+  pageInfo: PageInfo!
+  edges: [BlockInstanceEdge]!
+  aggregate: AggregateBlockInstance!
+}
+
+input BlockInstanceCreateInput {
+  id: ID
+  block: BlockCreateOneWithoutBlocksInput!
+  order: Int!
+  rounds: Int
+  variation: String
+}
+
+input BlockInstanceCreateManyInput {
+  create: [BlockInstanceCreateInput!]
+  connect: [BlockInstanceWhereUniqueInput!]
+}
+
+input BlockInstanceCreateManyWithoutBlockInput {
+  create: [BlockInstanceCreateWithoutBlockInput!]
+  connect: [BlockInstanceWhereUniqueInput!]
+}
+
+input BlockInstanceCreateWithoutBlockInput {
+  id: ID
+  order: Int!
+  rounds: Int
+  variation: String
+}
+
+type BlockInstanceEdge {
+  node: BlockInstance!
+  cursor: String!
+}
+
+enum BlockInstanceOrderByInput {
   id_ASC
   id_DESC
-  sequence_ASC
-  sequence_DESC
-  title_ASC
-  title_DESC
-  description_ASC
-  description_DESC
-  duration_ASC
-  duration_DESC
+  order_ASC
+  order_DESC
   rounds_ASC
   rounds_DESC
-  rest_ASC
-  rest_DESC
+  variation_ASC
+  variation_DESC
 }
 
-type BlockPreviousValues {
+type BlockInstancePreviousValues {
   id: ID!
-  sequence: Int!
-  title: String!
-  description: String
-  videos: [String!]!
-  pictures: [String!]!
-  duration: Int
+  order: Int!
   rounds: Int
-  rest: Int
+  variation: String
 }
 
-input BlockScalarWhereInput {
+input BlockInstanceScalarWhereInput {
   id: ID
   id_not: ID
   id_in: [ID!]
@@ -146,50 +192,166 @@ input BlockScalarWhereInput {
   id_not_starts_with: ID
   id_ends_with: ID
   id_not_ends_with: ID
-  sequence: Int
-  sequence_not: Int
-  sequence_in: [Int!]
-  sequence_not_in: [Int!]
-  sequence_lt: Int
-  sequence_lte: Int
-  sequence_gt: Int
-  sequence_gte: Int
-  title: String
-  title_not: String
-  title_in: [String!]
-  title_not_in: [String!]
-  title_lt: String
-  title_lte: String
-  title_gt: String
-  title_gte: String
-  title_contains: String
-  title_not_contains: String
-  title_starts_with: String
-  title_not_starts_with: String
-  title_ends_with: String
-  title_not_ends_with: String
-  description: String
-  description_not: String
-  description_in: [String!]
-  description_not_in: [String!]
-  description_lt: String
-  description_lte: String
-  description_gt: String
-  description_gte: String
-  description_contains: String
-  description_not_contains: String
-  description_starts_with: String
-  description_not_starts_with: String
-  description_ends_with: String
-  description_not_ends_with: String
-  duration: Int
-  duration_not: Int
-  duration_in: [Int!]
-  duration_not_in: [Int!]
-  duration_lt: Int
-  duration_lte: Int
-  duration_gt: Int
-  duration_gte: Int
+  order: Int
+  order_not: Int
+  order_in: [Int!]
+  order_not_in: [Int!]
+  order_lt: Int
+  order_lte: Int
+  order_gt: Int
+  order_gte: Int
+  rounds: Int
+  rounds_not: Int
+  rounds_in: [Int!]
+  rounds_not_in: [Int!]
+  rounds_lt: Int
+  rounds_lte: Int
+  rounds_gt: Int
+  rounds_gte: Int
+  variation: String
+  variation_not: String
+  variation_in: [String!]
+  variation_not_in: [String!]
+  variation_lt: String
+  variation_lte: String
+  variation_gt: String
+  variation_gte: String
+  variation_contains: String
+  variation_not_contains: String
+  variation_starts_with: String
+  variation_not_starts_with: String
+  variation_ends_with: String
+  variation_not_ends_with: String
+  AND: [BlockInstanceScalarWhereInput!]
+  OR: [BlockInstanceScalarWhereInput!]
+  NOT: [BlockInstanceScalarWhereInput!]
+}
+
+type BlockInstanceSubscriptionPayload {
+  mutation: MutationType!
+  node: BlockInstance
+  updatedFields: [String!]
+  previousValues: BlockInstancePreviousValues
+}
+
+input BlockInstanceSubscriptionWhereInput {
+  mutation_in: [MutationType!]
+  updatedFields_contains: String
+  updatedFields_contains_every: [String!]
+  updatedFields_contains_some: [String!]
+  node: BlockInstanceWhereInput
+  AND: [BlockInstanceSubscriptionWhereInput!]
+  OR: [BlockInstanceSubscriptionWhereInput!]
+  NOT: [BlockInstanceSubscriptionWhereInput!]
+}
+
+input BlockInstanceUpdateDataInput {
+  block: BlockUpdateOneRequiredWithoutBlocksInput
+  order: Int
+  rounds: Int
+  variation: String
+}
+
+input BlockInstanceUpdateInput {
+  block: BlockUpdateOneRequiredWithoutBlocksInput
+  order: Int
+  rounds: Int
+  variation: String
+}
+
+input BlockInstanceUpdateManyDataInput {
+  order: Int
+  rounds: Int
+  variation: String
+}
+
+input BlockInstanceUpdateManyInput {
+  create: [BlockInstanceCreateInput!]
+  update: [BlockInstanceUpdateWithWhereUniqueNestedInput!]
+  upsert: [BlockInstanceUpsertWithWhereUniqueNestedInput!]
+  delete: [BlockInstanceWhereUniqueInput!]
+  connect: [BlockInstanceWhereUniqueInput!]
+  set: [BlockInstanceWhereUniqueInput!]
+  disconnect: [BlockInstanceWhereUniqueInput!]
+  deleteMany: [BlockInstanceScalarWhereInput!]
+  updateMany: [BlockInstanceUpdateManyWithWhereNestedInput!]
+}
+
+input BlockInstanceUpdateManyMutationInput {
+  order: Int
+  rounds: Int
+  variation: String
+}
+
+input BlockInstanceUpdateManyWithoutBlockInput {
+  create: [BlockInstanceCreateWithoutBlockInput!]
+  delete: [BlockInstanceWhereUniqueInput!]
+  connect: [BlockInstanceWhereUniqueInput!]
+  set: [BlockInstanceWhereUniqueInput!]
+  disconnect: [BlockInstanceWhereUniqueInput!]
+  update: [BlockInstanceUpdateWithWhereUniqueWithoutBlockInput!]
+  upsert: [BlockInstanceUpsertWithWhereUniqueWithoutBlockInput!]
+  deleteMany: [BlockInstanceScalarWhereInput!]
+  updateMany: [BlockInstanceUpdateManyWithWhereNestedInput!]
+}
+
+input BlockInstanceUpdateManyWithWhereNestedInput {
+  where: BlockInstanceScalarWhereInput!
+  data: BlockInstanceUpdateManyDataInput!
+}
+
+input BlockInstanceUpdateWithoutBlockDataInput {
+  order: Int
+  rounds: Int
+  variation: String
+}
+
+input BlockInstanceUpdateWithWhereUniqueNestedInput {
+  where: BlockInstanceWhereUniqueInput!
+  data: BlockInstanceUpdateDataInput!
+}
+
+input BlockInstanceUpdateWithWhereUniqueWithoutBlockInput {
+  where: BlockInstanceWhereUniqueInput!
+  data: BlockInstanceUpdateWithoutBlockDataInput!
+}
+
+input BlockInstanceUpsertWithWhereUniqueNestedInput {
+  where: BlockInstanceWhereUniqueInput!
+  update: BlockInstanceUpdateDataInput!
+  create: BlockInstanceCreateInput!
+}
+
+input BlockInstanceUpsertWithWhereUniqueWithoutBlockInput {
+  where: BlockInstanceWhereUniqueInput!
+  update: BlockInstanceUpdateWithoutBlockDataInput!
+  create: BlockInstanceCreateWithoutBlockInput!
+}
+
+input BlockInstanceWhereInput {
+  id: ID
+  id_not: ID
+  id_in: [ID!]
+  id_not_in: [ID!]
+  id_lt: ID
+  id_lte: ID
+  id_gt: ID
+  id_gte: ID
+  id_contains: ID
+  id_not_contains: ID
+  id_starts_with: ID
+  id_not_starts_with: ID
+  id_ends_with: ID
+  id_not_ends_with: ID
+  block: BlockWhereInput
+  order: Int
+  order_not: Int
+  order_in: [Int!]
+  order_not_in: [Int!]
+  order_lt: Int
+  order_lte: Int
+  order_gt: Int
+  order_gte: Int
   rounds: Int
   rounds_not: Int
   rounds_in: [Int!]
@@ -198,17 +360,50 @@ input BlockScalarWhereInput {
   rounds_lte: Int
   rounds_gt: Int
   rounds_gte: Int
+  variation: String
+  variation_not: String
+  variation_in: [String!]
+  variation_not_in: [String!]
+  variation_lt: String
+  variation_lte: String
+  variation_gt: String
+  variation_gte: String
+  variation_contains: String
+  variation_not_contains: String
+  variation_starts_with: String
+  variation_not_starts_with: String
+  variation_ends_with: String
+  variation_not_ends_with: String
+  AND: [BlockInstanceWhereInput!]
+  OR: [BlockInstanceWhereInput!]
+  NOT: [BlockInstanceWhereInput!]
+}
+
+input BlockInstanceWhereUniqueInput {
+  id: ID
+}
+
+enum BlockOrderByInput {
+  id_ASC
+  id_DESC
+  title_ASC
+  title_DESC
+  description_ASC
+  description_DESC
+  duration_ASC
+  duration_DESC
+  rest_ASC
+  rest_DESC
+}
+
+type BlockPreviousValues {
+  id: ID!
+  title: String!
+  description: String
+  videos: [String!]!
+  pictures: [String!]!
+  duration: Int
   rest: Int
-  rest_not: Int
-  rest_in: [Int!]
-  rest_not_in: [Int!]
-  rest_lt: Int
-  rest_lte: Int
-  rest_gt: Int
-  rest_gte: Int
-  AND: [BlockScalarWhereInput!]
-  OR: [BlockScalarWhereInput!]
-  NOT: [BlockScalarWhereInput!]
 }
 
 type BlockSubscriptionPayload {
@@ -229,73 +424,33 @@ input BlockSubscriptionWhereInput {
   NOT: [BlockSubscriptionWhereInput!]
 }
 
-input BlockUpdateDataInput {
-  sequence: Int
-  title: String
-  description: String
-  videos: BlockUpdatevideosInput
-  pictures: BlockUpdatepicturesInput
-  duration: Int
-  rounds: Int
-  format: FormatUpdateOneRequiredInput
-  rest: Int
-  tracks: TrackUpdateManyInput
-  blocks: BlockUpdateManyInput
-  exercises: ExerciseInstanceUpdateManyInput
-}
-
 input BlockUpdateInput {
-  sequence: Int
   title: String
   description: String
   videos: BlockUpdatevideosInput
   pictures: BlockUpdatepicturesInput
   duration: Int
-  rounds: Int
   format: FormatUpdateOneRequiredInput
   rest: Int
   tracks: TrackUpdateManyInput
-  blocks: BlockUpdateManyInput
+  blocks: BlockInstanceUpdateManyWithoutBlockInput
   exercises: ExerciseInstanceUpdateManyInput
 }
 
-input BlockUpdateManyDataInput {
-  sequence: Int
-  title: String
-  description: String
-  videos: BlockUpdatevideosInput
-  pictures: BlockUpdatepicturesInput
-  duration: Int
-  rounds: Int
-  rest: Int
-}
-
-input BlockUpdateManyInput {
-  create: [BlockCreateInput!]
-  update: [BlockUpdateWithWhereUniqueNestedInput!]
-  upsert: [BlockUpsertWithWhereUniqueNestedInput!]
-  delete: [BlockWhereUniqueInput!]
-  connect: [BlockWhereUniqueInput!]
-  set: [BlockWhereUniqueInput!]
-  disconnect: [BlockWhereUniqueInput!]
-  deleteMany: [BlockScalarWhereInput!]
-  updateMany: [BlockUpdateManyWithWhereNestedInput!]
-}
-
 input BlockUpdateManyMutationInput {
-  sequence: Int
   title: String
   description: String
   videos: BlockUpdatevideosInput
   pictures: BlockUpdatepicturesInput
   duration: Int
-  rounds: Int
   rest: Int
 }
 
-input BlockUpdateManyWithWhereNestedInput {
-  where: BlockScalarWhereInput!
-  data: BlockUpdateManyDataInput!
+input BlockUpdateOneRequiredWithoutBlocksInput {
+  create: BlockCreateWithoutBlocksInput
+  update: BlockUpdateWithoutBlocksDataInput
+  upsert: BlockUpsertWithoutBlocksInput
+  connect: BlockWhereUniqueInput
 }
 
 input BlockUpdatepicturesInput {
@@ -306,15 +461,21 @@ input BlockUpdatevideosInput {
   set: [String!]
 }
 
-input BlockUpdateWithWhereUniqueNestedInput {
-  where: BlockWhereUniqueInput!
-  data: BlockUpdateDataInput!
+input BlockUpdateWithoutBlocksDataInput {
+  title: String
+  description: String
+  videos: BlockUpdatevideosInput
+  pictures: BlockUpdatepicturesInput
+  duration: Int
+  format: FormatUpdateOneRequiredInput
+  rest: Int
+  tracks: TrackUpdateManyInput
+  exercises: ExerciseInstanceUpdateManyInput
 }
 
-input BlockUpsertWithWhereUniqueNestedInput {
-  where: BlockWhereUniqueInput!
-  update: BlockUpdateDataInput!
-  create: BlockCreateInput!
+input BlockUpsertWithoutBlocksInput {
+  update: BlockUpdateWithoutBlocksDataInput!
+  create: BlockCreateWithoutBlocksInput!
 }
 
 input BlockWhereInput {
@@ -332,14 +493,6 @@ input BlockWhereInput {
   id_not_starts_with: ID
   id_ends_with: ID
   id_not_ends_with: ID
-  sequence: Int
-  sequence_not: Int
-  sequence_in: [Int!]
-  sequence_not_in: [Int!]
-  sequence_lt: Int
-  sequence_lte: Int
-  sequence_gt: Int
-  sequence_gte: Int
   title: String
   title_not: String
   title_in: [String!]
@@ -376,14 +529,6 @@ input BlockWhereInput {
   duration_lte: Int
   duration_gt: Int
   duration_gte: Int
-  rounds: Int
-  rounds_not: Int
-  rounds_in: [Int!]
-  rounds_not_in: [Int!]
-  rounds_lt: Int
-  rounds_lte: Int
-  rounds_gt: Int
-  rounds_gte: Int
   format: FormatWhereInput
   rest: Int
   rest_not: Int
@@ -396,9 +541,9 @@ input BlockWhereInput {
   tracks_every: TrackWhereInput
   tracks_some: TrackWhereInput
   tracks_none: TrackWhereInput
-  blocks_every: BlockWhereInput
-  blocks_some: BlockWhereInput
-  blocks_none: BlockWhereInput
+  blocks_every: BlockInstanceWhereInput
+  blocks_some: BlockInstanceWhereInput
+  blocks_none: BlockInstanceWhereInput
   exercises_every: ExerciseInstanceWhereInput
   exercises_some: ExerciseInstanceWhereInput
   exercises_none: ExerciseInstanceWhereInput
@@ -618,7 +763,8 @@ type Exercise {
   id: ID!
   name: String!
   description: String!
-  video: String!
+  videos: [String!]!
+  pictures: [String!]!
   targets: [String!]!
   baseExercise: [String!]!
 }
@@ -637,7 +783,8 @@ input ExerciseCreateInput {
   id: ID
   name: String!
   description: String!
-  video: String!
+  videos: ExerciseCreatevideosInput
+  pictures: ExerciseCreatepicturesInput
   targets: ExerciseCreatetargetsInput
   baseExercise: ExerciseCreatebaseExerciseInput
 }
@@ -647,10 +794,18 @@ input ExerciseCreateOneInput {
   connect: ExerciseWhereUniqueInput
 }
 
+input ExerciseCreatepicturesInput {
+  set: [String!]
+}
+
 input ExerciseCreatetargetsInput {
   set: [String!]
 }
 
+input ExerciseCreatevideosInput {
+  set: [String!]
+}
+
 type ExerciseEdge {
   node: Exercise!
   cursor: String!
@@ -659,7 +814,9 @@ type ExerciseEdge {
 type ExerciseInstance {
   id: ID!
   exercise: Exercise!
+  order: Int!
   repetitions: Int
+  variation: String
 }
 
 type ExerciseInstanceConnection {
@@ -671,7 +828,9 @@ type ExerciseInstanceConnection {
 input ExerciseInstanceCreateInput {
   id: ID
   exercise: ExerciseCreateOneInput!
+  order: Int!
   repetitions: Int
+  variation: String
 }
 
 input ExerciseInstanceCreateManyInput {
@@ -687,13 +846,19 @@ type ExerciseInstanceEdge {
 enum ExerciseInstanceOrderByInput {
   id_ASC
   id_DESC
+  order_ASC
+  order_DESC
   repetitions_ASC
   repetitions_DESC
+  variation_ASC
+  variation_DESC
 }
 
 type ExerciseInstancePreviousValues {
   id: ID!
+  order: Int!
   repetitions: Int
+  variation: String
 }
 
 input ExerciseInstanceScalarWhereInput {
@@ -711,6 +876,14 @@ input ExerciseInstanceScalarWhereInput {
   id_not_starts_with: ID
   id_ends_with: ID
   id_not_ends_with: ID
+  order: Int
+  order_not: Int
+  order_in: [Int!]
+  order_not_in: [Int!]
+  order_lt: Int
+  order_lte: Int
+  order_gt: Int
+  order_gte: Int
   repetitions: Int
   repetitions_not: Int
   repetitions_in: [Int!]
@@ -719,6 +892,20 @@ input ExerciseInstanceScalarWhereInput {
   repetitions_lte: Int
   repetitions_gt: Int
   repetitions_gte: Int
+  variation: String
+  variation_not: String
+  variation_in: [String!]
+  variation_not_in: [String!]
+  variation_lt: String
+  variation_lte: String
+  variation_gt: String
+  variation_gte: String
+  variation_contains: String
+  variation_not_contains: String
+  variation_starts_with: String
+  variation_not_starts_with: String
+  variation_ends_with: String
+  variation_not_ends_with: String
   AND: [ExerciseInstanceScalarWhereInput!]
   OR: [ExerciseInstanceScalarWhereInput!]
   NOT: [ExerciseInstanceScalarWhereInput!]
@@ -744,16 +931,22 @@ input ExerciseInstanceSubscriptionWhereInput {
 
 input ExerciseInstanceUpdateDataInput {
   exercise: ExerciseUpdateOneRequiredInput
+  order: Int
   repetitions: Int
+  variation: String
 }
 
 input ExerciseInstanceUpdateInput {
   exercise: ExerciseUpdateOneRequiredInput
+  order: Int
   repetitions: Int
+  variation: String
 }
 
 input ExerciseInstanceUpdateManyDataInput {
+  order: Int
   repetitions: Int
+  variation: String
 }
 
 input ExerciseInstanceUpdateManyInput {
@@ -769,7 +962,9 @@ input ExerciseInstanceUpdateManyInput {
 }
 
 input ExerciseInstanceUpdateManyMutationInput {
+  order: Int
   repetitions: Int
+  variation: String
 }
 
 input ExerciseInstanceUpdateManyWithWhereNestedInput {
@@ -804,6 +999,14 @@ input ExerciseInstanceWhereInput {
   id_ends_with: ID
   id_not_ends_with: ID
   exercise: ExerciseWhereInput
+  order: Int
+  order_not: Int
+  order_in: [Int!]
+  order_not_in: [Int!]
+  order_lt: Int
+  order_lte: Int
+  order_gt: Int
+  order_gte: Int
   repetitions: Int
   repetitions_not: Int
   repetitions_in: [Int!]
@@ -812,6 +1015,20 @@ input ExerciseInstanceWhereInput {
   repetitions_lte: Int
   repetitions_gt: Int
   repetitions_gte: Int
+  variation: String
+  variation_not: String
+  variation_in: [String!]
+  variation_not_in: [String!]
+  variation_lt: String
+  variation_lte: String
+  variation_gt: String
+  variation_gte: String
+  variation_contains: String
+  variation_not_contains: String
+  variation_starts_with: String
+  variation_not_starts_with: String
+  variation_ends_with: String
+  variation_not_ends_with: String
   AND: [ExerciseInstanceWhereInput!]
   OR: [ExerciseInstanceWhereInput!]
   NOT: [ExerciseInstanceWhereInput!]
@@ -828,15 +1045,14 @@ enum ExerciseOrderByInput {
   name_DESC
   description_ASC
   description_DESC
-  video_ASC
-  video_DESC
 }
 
 type ExercisePreviousValues {
   id: ID!
   name: String!
   description: String!
-  video: String!
+  videos: [String!]!
+  pictures: [String!]!
   targets: [String!]!
   baseExercise: [String!]!
 }
@@ -866,7 +1082,8 @@ input ExerciseUpdatebaseExerciseInput {
 input ExerciseUpdateDataInput {
   name: String
   description: String
-  video: String
+  videos: ExerciseUpdatevideosInput
+  pictures: ExerciseUpdatepicturesInput
   targets: ExerciseUpdatetargetsInput
   baseExercise: ExerciseUpdatebaseExerciseInput
 }
@@ -874,7 +1091,8 @@ input ExerciseUpdateDataInput {
 input ExerciseUpdateInput {
   name: String
   description: String
-  video: String
+  videos: ExerciseUpdatevideosInput
+  pictures: ExerciseUpdatepicturesInput
   targets: ExerciseUpdatetargetsInput
   baseExercise: ExerciseUpdatebaseExerciseInput
 }
@@ -882,7 +1100,8 @@ input ExerciseUpdateInput {
 input ExerciseUpdateManyMutationInput {
   name: String
   description: String
-  video: String
+  videos: ExerciseUpdatevideosInput
+  pictures: ExerciseUpdatepicturesInput
   targets: ExerciseUpdatetargetsInput
   baseExercise: ExerciseUpdatebaseExerciseInput
 }
@@ -894,10 +1113,18 @@ input ExerciseUpdateOneRequiredInput {
   connect: ExerciseWhereUniqueInput
 }
 
+input ExerciseUpdatepicturesInput {
+  set: [String!]
+}
+
 input ExerciseUpdatetargetsInput {
   set: [String!]
 }
 
+input ExerciseUpdatevideosInput {
+  set: [String!]
+}
+
 input ExerciseUpsertNestedInput {
   update: ExerciseUpdateDataInput!
   create: ExerciseCreateInput!
@@ -946,20 +1173,6 @@ input ExerciseWhereInput {
   description_not_starts_with: String
   description_ends_with: String
   description_not_ends_with: String
-  video: String
-  video_not: String
-  video_in: [String!]
-  video_not_in: [String!]
-  video_lt: String
-  video_lte: String
-  video_gt: String
-  video_gte: String
-  video_contains: String
-  video_not_contains: String
-  video_starts_with: String
-  video_not_starts_with: String
-  video_ends_with: String
-  video_not_ends_with: String
   AND: [ExerciseWhereInput!]
   OR: [ExerciseWhereInput!]
   NOT: [ExerciseWhereInput!]
@@ -1118,6 +1331,12 @@ type Mutation {
   upsertBlock(where: BlockWhereUniqueInput!, create: BlockCreateInput!, update: BlockUpdateInput!): Block!
   deleteBlock(where: BlockWhereUniqueInput!): Block
   deleteManyBlocks(where: BlockWhereInput): BatchPayload!
+  createBlockInstance(data: BlockInstanceCreateInput!): BlockInstance!
+  updateBlockInstance(data: BlockInstanceUpdateInput!, where: BlockInstanceWhereUniqueInput!): BlockInstance
+  updateManyBlockInstances(data: BlockInstanceUpdateManyMutationInput!, where: BlockInstanceWhereInput): BatchPayload!
+  upsertBlockInstance(where: BlockInstanceWhereUniqueInput!, create: BlockInstanceCreateInput!, update: BlockInstanceUpdateInput!): BlockInstance!
+  deleteBlockInstance(where: BlockInstanceWhereUniqueInput!): BlockInstance
+  deleteManyBlockInstances(where: BlockInstanceWhereInput): BatchPayload!
   createComment(data: CommentCreateInput!): Comment!
   updateComment(data: CommentUpdateInput!, where: CommentWhereUniqueInput!): Comment
   updateManyComments(data: CommentUpdateManyMutationInput!, where: CommentWhereInput): BatchPayload!
@@ -1200,6 +1419,9 @@ type Query {
   block(where: BlockWhereUniqueInput!): Block
   blocks(where: BlockWhereInput, orderBy: BlockOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Block]!
   blocksConnection(where: BlockWhereInput, orderBy: BlockOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): BlockConnection!
+  blockInstance(where: BlockInstanceWhereUniqueInput!): BlockInstance
+  blockInstances(where: BlockInstanceWhereInput, orderBy: BlockInstanceOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [BlockInstance]!
+  blockInstancesConnection(where: BlockInstanceWhereInput, orderBy: BlockInstanceOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): BlockInstanceConnection!
   comment(where: CommentWhereUniqueInput!): Comment
   comments(where: CommentWhereInput, orderBy: CommentOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Comment]!
   commentsConnection(where: CommentWhereInput, orderBy: CommentOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): CommentConnection!
@@ -1493,6 +1715,7 @@ input RatingWhereUniqueInput {
 
 type Subscription {
   block(where: BlockSubscriptionWhereInput): BlockSubscriptionPayload
+  blockInstance(where: BlockInstanceSubscriptionWhereInput): BlockInstanceSubscriptionPayload
   comment(where: CommentSubscriptionWhereInput): CommentSubscriptionPayload
   exercise(where: ExerciseSubscriptionWhereInput): ExerciseSubscriptionPayload
   exerciseInstance(where: ExerciseInstanceSubscriptionWhereInput): ExerciseInstanceSubscriptionPayload
@@ -1786,7 +2009,7 @@ type Training {
   attendance: Int
   ratings(where: RatingWhereInput, orderBy: RatingOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Rating!]
   published: Boolean!
-  blocks(where: BlockWhereInput, orderBy: BlockOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Block!]
+  blocks(where: BlockInstanceWhereInput, orderBy: BlockInstanceOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [BlockInstance!]
 }
 
 type TrainingConnection {
@@ -1805,7 +2028,7 @@ input TrainingCreateInput {
   attendance: Int
   ratings: RatingCreateManyInput
   published: Boolean!
-  blocks: BlockCreateManyInput
+  blocks: BlockInstanceCreateManyInput
 }
 
 type TrainingEdge {
@@ -2008,7 +2231,7 @@ input TrainingUpdateInput {
   attendance: Int
   ratings: RatingUpdateManyInput
   published: Boolean
-  blocks: BlockUpdateManyInput
+  blocks: BlockInstanceUpdateManyInput
 }
 
 input TrainingUpdateManyMutationInput {
@@ -2095,9 +2318,9 @@ input TrainingWhereInput {
   ratings_none: RatingWhereInput
   published: Boolean
   published_not: Boolean
-  blocks_every: BlockWhereInput
-  blocks_some: BlockWhereInput
-  blocks_none: BlockWhereInput
+  blocks_every: BlockInstanceWhereInput
+  blocks_some: BlockInstanceWhereInput
+  blocks_none: BlockInstanceWhereInput
   AND: [TrainingWhereInput!]
   OR: [TrainingWhereInput!]
   NOT: [TrainingWhereInput!]

Datei-Diff unterdrückt, da er zu groß ist
+ 474 - 187
backend/database/generated/prisma.graphql


+ 20 - 11
backend/datamodel.prisma

@@ -28,7 +28,7 @@ type Training {
     attendance: Int
     ratings: [Rating!]!
     published: Boolean!
-    blocks: [Block!]!
+    blocks: [BlockInstance!]!
 }
 
 type TrainingType {
@@ -39,20 +39,26 @@ type TrainingType {
 
 type Block {
     id: ID! @id
-    sequence: Int!
     title: String!
     description: String
     videos: [String!]! @scalarList(strategy: RELATION)
     pictures: [String!]! @scalarList(strategy: RELATION)
     duration: Int
-    rounds: Int
     format: Format!
     rest: Int
     tracks: [Track!]!
-    blocks: [Block!]!
+    blocks: [BlockInstance!]!
     exercises: [ExerciseInstance!]!
 }
 
+type BlockInstance {
+    id: ID! @id
+    block: Block!
+    order: Int!
+    rounds: Int
+    variation: String
+}
+
 type Format {
     id: ID! @id
     name: String!
@@ -67,21 +73,24 @@ type Track {
     link: String!
 }
 
-type ExerciseInstance {
-    id: ID! @id
-    exercise: Exercise!
-    repetitions: Int
-}
-
 type Exercise {
     id: ID! @id
     name: String!
     description: String!
-    video: String!
+    videos: [String!]! @scalarList(strategy: RELATION)
+    pictures: [String!]! @scalarList(strategy: RELATION)
     targets: [String!]! @scalarList(strategy: RELATION)
     baseExercise: [String!]! @scalarList(strategy: RELATION)
 }
 
+type ExerciseInstance {
+    id: ID! @id
+    exercise: Exercise!
+    order: Int!
+    repetitions: Int
+    variation: String
+}
+
 type Rating {
     id: ID! @id
     user: User!

+ 1 - 1
backend/index.ts

@@ -52,7 +52,7 @@ server.applyMiddleware({ app, cors: corsOptions })
 
 app.listen({ port: process.env.PORT }, () => {
   console.log(
-    `Server ready at http://localhost:${process.env.PORT}/${server.graphqlPath}.`
+    `Server ready at http://localhost:${process.env.PORT}/${server.graphqlPath} 🚀`
   )
 })
 

+ 27 - 12
backend/schema.graphql

@@ -1,6 +1,8 @@
 # import * from './database/generated/prisma.graphql'
 
 type Query {
+  currentUser: User!
+  user(where: UserWhereUniqueInput!): User
   users(
     where: UserWhereInput
     orderBy: UserOrderByInput
@@ -10,7 +12,7 @@ type Query {
     first: Int
     last: Int
   ): [User!]!
-  training(where: TrainingWhereUniqueInput!): Training
+  training(id: ID!): Training
   trainings(
     where: TrainingWhereInput
     orderBy: TrainingOrderByInput
@@ -30,6 +32,7 @@ type Query {
     first: Int
     last: Int
   ): [TrainingType!]!
+  block(where: BlockWhereUniqueInput!): Block
   blocks(
     where: BlockWhereInput
     orderBy: BlockOrderByInput
@@ -39,6 +42,7 @@ type Query {
     first: Int
     last: Int
   ): [Block!]!
+  format(where: FormatWhereUniqueInput!): Format
   formats(
     where: FormatWhereInput
     orderBy: FormatOrderByInput
@@ -48,7 +52,16 @@ type Query {
     first: Int
     last: Int
   ): [Format!]!
-  currentUser: User!
+  exercise(where: ExerciseWhereUniqueInput!): Exercise
+  exercises(
+    where: ExerciseWhereInput
+    orderBy: ExerciseOrderByInput
+    skip: Int
+    after: String
+    before: String
+    first: Int
+    last: Int
+  ): [Exercise!]!
 }
 
 type Mutation {
@@ -59,21 +72,23 @@ type Mutation {
     title: String!
     type: TrainingTypeCreateOneInput!
     trainingDate: DateTime!
-    location: String!
-    attendance: Int!
+    location: String
+    attendance: Int
     published: Boolean!
-    blocks: BlockCreateManyInput
+    blocks: BlockInstanceCreateManyInput
   ): Training!
   createTrainingType(name: String!, description: String!): TrainingType!
   createBlock(
-    sequence: Int!
     title: String!
-    duration: Int!
-    variation: String
-    format: ID
-    tracks: [ID]!
-    exercises: [ID]!
-    description: String!
+    description: String
+    videos: [String!]
+    pictures: [String!]
+    duration: Int
+    format: FormatCreateOneInput!
+    rest: Int
+    tracks: TrackCreateManyInput
+    blocks: BlockInstanceCreateManyWithoutBlockInput
+    exercises: ExerciseInstanceCreateManyInput
   ): Block!
   createFormat(name: String!, description: String!): Format!
   userLogin(email: String!, password: String!): User!

+ 1 - 2
backend/src/training/resolvers.ts

@@ -10,7 +10,7 @@ export const resolvers: IResolvers = {
   Query: {
     training: async (parent, args, context, info) => {
       checkPermission(context)
-      return context.db.query.training({ data: args }, info)
+      return context.db.query.training({ where: args }, info)
     },
     trainings: async (parent, args, context, info) => {
       checkPermission(context)
@@ -37,7 +37,6 @@ export const resolvers: IResolvers = {
         { data: args },
         info
       )
-      console.log('post saving.')
       return training
     },
     createTrainingType: async (parent, args, context, info) => {

+ 5 - 0
frontend/.vscode/settings.json

@@ -0,0 +1,5 @@
+{
+    "prettier.jsxSingleQuote": true,
+    "prettier.semi": false,
+    "prettier.singleQuote": true
+}

+ 28 - 0
frontend/package-lock.json

@@ -2966,6 +2966,14 @@
         "@types/react": "*"
       }
     },
+    "@types/react-onclickoutside": {
+      "version": "6.7.3",
+      "resolved": "https://registry.npmjs.org/@types/react-onclickoutside/-/react-onclickoutside-6.7.3.tgz",
+      "integrity": "sha512-ByQX2ns3KlOrOzJBVhQ2VZmQVV6w718TXFVAdCdHBeXMXr5QseQVN+BsOmLf2+KZGz7+Y4ov9jPxRDCDNJZMLg==",
+      "requires": {
+        "@types/react": "*"
+      }
+    },
     "@types/react-test-renderer": {
       "version": "16.9.1",
       "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-16.9.1.tgz",
@@ -3739,6 +3747,11 @@
         "is-string": "^1.0.5"
       }
     },
+    "array-move": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/array-move/-/array-move-2.2.1.tgz",
+      "integrity": "sha512-qQpEHBnVT6HAFgEVUwRdHVd8TYJThrZIT5wSXpEUTPwBaYhPLclw12mEpyUvRWVdl1VwPOqnIy6LqTFN3cSeUQ=="
+    },
     "array-union": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
@@ -10968,6 +10981,21 @@
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
       "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA=="
     },
+    "react-onclickoutside": {
+      "version": "6.9.0",
+      "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.9.0.tgz",
+      "integrity": "sha512-8ltIY3bC7oGhj2nPAvWOGi+xGFybPNhJM0V1H8hY/whNcXgmDeaeoCMPPd8VatrpTsUWjb/vGzrmu6SrXVty3A=="
+    },
+    "react-sortable-hoc": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/react-sortable-hoc/-/react-sortable-hoc-1.11.0.tgz",
+      "integrity": "sha512-v1CDCvdfoR3zLGNp6qsBa4J1BWMEVH25+UKxF/RvQRh+mrB+emqtVHMgZ+WreUiKJoEaiwYoScaueIKhMVBHUg==",
+      "requires": {
+        "@babel/runtime": "^7.2.0",
+        "invariant": "^2.2.4",
+        "prop-types": "^15.5.7"
+      }
+    },
     "react-test-renderer": {
       "version": "16.13.1",
       "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.13.1.tgz",

+ 4 - 0
frontend/package.json

@@ -16,11 +16,13 @@
     "@types/howler": "^2.1.2",
     "@types/jest": "24.9.1",
     "@types/lodash": "^4.14.149",
+    "@types/react-onclickoutside": "^6.7.3",
     "@types/styled-jsx": "^2.2.8",
     "@types/video.js": "7.3.6",
     "apollo-boost": "0.4.7",
     "apollo-link": "^1.2.13",
     "apollo-link-error": "^1.1.12",
+    "array-move": "^2.2.1",
     "date-fns": "^2.11.1",
     "dotenv": "^8.2.0",
     "formik": "2.1.4",
@@ -35,6 +37,8 @@
     "nprogress": "^0.2.0",
     "react": "16.13.1",
     "react-dom": "16.11.0",
+    "react-onclickoutside": "^6.9.0",
+    "react-sortable-hoc": "^1.11.0",
     "standard": "14.3.3",
     "video.js": "^7.7.5",
     "yup": "^0.27.0"

+ 1 - 3
frontend/pages/admin/users.js → frontend/pages/admin/users.tsx

@@ -7,9 +7,7 @@ const UserAdminPage = () => {
   const { data, loading, error } = useCurrentUserQuery()
   console.log('UserPage', data, loading, error && error.message)
 
-  return (
-    <UserAdmin />
-  )
+  return <UserAdmin />
 }
 
 export default withRouter(UserAdminPage)

+ 0 - 7
frontend/pages/training.tsx

@@ -1,7 +0,0 @@
-import NewTraining from '../src/training/components/EditTraining'
-
-const TrainingPage = () => {
-  return <NewTraining />
-}
-
-export default TrainingPage

+ 14 - 0
frontend/pages/training/[id].tsx

@@ -0,0 +1,14 @@
+import EditTraining from '../../src/training/components/EditTraining'
+import { useRouter } from 'next/router'
+
+const TrainingPage = () => {
+  const router = useRouter()
+
+  return (
+    <EditTraining
+      id={typeof router.query.id === 'string' ? router.query.id : undefined}
+    />
+  )
+}
+
+export default TrainingPage

+ 7 - 0
frontend/pages/training/index.tsx

@@ -0,0 +1,7 @@
+import TrainingsList from '../../src/training/components/TrainingsList'
+
+const TrainingPage = () => {
+  return <TrainingsList />
+}
+
+export default TrainingPage

+ 85 - 0
frontend/src/dropdown/components/Dropdown.tsx

@@ -0,0 +1,85 @@
+import React, { useState, ReactChild, FunctionComponent } from 'react'
+import onClickOutside from 'react-onclickoutside'
+
+interface IDropdown {
+  items?: {
+    key: string | number
+    title: string | ReactChild
+    content: ReactChild
+  }[]
+  selectItem: (key: number | string) => void
+}
+
+const Dropdown: FunctionComponent<IDropdown> & {
+  handleClickOutside?: () => void
+} = ({ items, selectItem }: IDropdown) => {
+  const [open, setOpen] = useState(false)
+  const [active, setActive] = useState<undefined | string | number>()
+  Dropdown.handleClickOutside = () => setOpen(false)
+
+  const activeItem =
+    active !== undefined && items && items.find(item => item.key === active)
+
+  return (
+    <div id='dd-container'>
+      <div id='dd-header'>
+        <p onClick={event => setOpen(!open)}>
+          {activeItem ? activeItem.title : 'please select one'}
+        </p>
+      </div>
+      <ul id='dd-items'>
+        {items &&
+          items.map(item => (
+            <li
+              key={item.key}
+              onClick={() => {
+                setActive(item.key)
+                selectItem(item.key)
+                setOpen(false)
+              }}
+            >
+              {typeof item.content === 'string' ? (
+                <p className={active === item.key ? 'active' : undefined}>
+                  {item.content}
+                </p>
+              ) : (
+                item.content
+              )}
+            </li>
+          ))}
+      </ul>
+      <div>{open ? 'open' : 'closed'}</div>
+      <div>{active}</div>
+
+      <style jsx>{`
+        #dd-container {
+          position: relative;
+          margin: 0;
+          padding: 0;
+        }
+
+        #dd-header p {
+          background-color: #995555;
+          margin: 0;
+          padding: 0;
+        }
+
+        #dd-items {
+          display: ${open ? 'block' : 'none'};
+          position: absolute;
+          width: 100%;
+          max-height: 300px;
+          z-index: 5;
+          overflow-y: scroll;
+          margin: 0;
+          padding: 0;
+          background-color: #559955;
+        }
+      `}</style>
+    </div>
+  )
+}
+
+export default onClickOutside(Dropdown, {
+  handleClickOutside: () => Dropdown.handleClickOutside
+})

+ 3 - 0
frontend/src/dropdown/index.tsx

@@ -0,0 +1,3 @@
+import Dropdown from './components/Dropdown'
+
+export default { Dropdown }

+ 5 - 1
frontend/src/form/hooks/useForm.tsx

@@ -8,6 +8,10 @@ export function useForm<T extends Dict>(initialValues: T) {
     .filter(([key, value]) => value !== values[key])
     .map(([key]) => key)
 
+  function loadData(values: T) {
+    setValues(values)
+  }
+
   function onChange(
     event:
       | ChangeEvent<HTMLInputElement>
@@ -29,5 +33,5 @@ export function useForm<T extends Dict>(initialValues: T) {
     }
   }
 
-  return { values, touched, onChange }
+  return { values, touched, onChange, loadData }
 }

+ 342 - 107
frontend/src/gql/index.tsx

@@ -16,17 +16,15 @@ export type Scalars = {
 
 export type Block = Node & {
   id: Scalars['ID'],
-  sequence: Scalars['Int'],
   title: Scalars['String'],
   description?: Maybe<Scalars['String']>,
   videos: Array<Scalars['String']>,
   pictures: Array<Scalars['String']>,
   duration?: Maybe<Scalars['Int']>,
-  rounds?: Maybe<Scalars['Int']>,
   format: Format,
   rest?: Maybe<Scalars['Int']>,
   tracks?: Maybe<Array<Track>>,
-  blocks?: Maybe<Array<Block>>,
+  blocks?: Maybe<Array<BlockInstance>>,
   exercises?: Maybe<Array<ExerciseInstance>>,
 };
 
@@ -43,8 +41,8 @@ export type BlockTracksArgs = {
 
 
 export type BlockBlocksArgs = {
-  where?: Maybe<BlockWhereInput>,
-  orderBy?: Maybe<BlockOrderByInput>,
+  where?: Maybe<BlockInstanceWhereInput>,
+  orderBy?: Maybe<BlockInstanceOrderByInput>,
   skip?: Maybe<Scalars['Int']>,
   after?: Maybe<Scalars['String']>,
   before?: Maybe<Scalars['String']>,
@@ -63,48 +61,183 @@ export type BlockExercisesArgs = {
   last?: Maybe<Scalars['Int']>
 };
 
-export type BlockCreateInput = {
+export type BlockCreateOneWithoutBlocksInput = {
+  create?: Maybe<BlockCreateWithoutBlocksInput>,
+  connect?: Maybe<BlockWhereUniqueInput>,
+};
+
+export type BlockCreatepicturesInput = {
+  set?: Maybe<Array<Scalars['String']>>,
+};
+
+export type BlockCreatevideosInput = {
+  set?: Maybe<Array<Scalars['String']>>,
+};
+
+export type BlockCreateWithoutBlocksInput = {
   id?: Maybe<Scalars['ID']>,
-  sequence: Scalars['Int'],
   title: Scalars['String'],
   description?: Maybe<Scalars['String']>,
   duration?: Maybe<Scalars['Int']>,
-  rounds?: Maybe<Scalars['Int']>,
   rest?: Maybe<Scalars['Int']>,
   videos?: Maybe<BlockCreatevideosInput>,
   pictures?: Maybe<BlockCreatepicturesInput>,
   format: FormatCreateOneInput,
   tracks?: Maybe<TrackCreateManyInput>,
-  blocks?: Maybe<BlockCreateManyInput>,
   exercises?: Maybe<ExerciseInstanceCreateManyInput>,
 };
 
-export type BlockCreateManyInput = {
-  create?: Maybe<Array<BlockCreateInput>>,
-  connect?: Maybe<Array<BlockWhereUniqueInput>>,
+export type BlockInstance = Node & {
+  id: Scalars['ID'],
+  block: Block,
+  order: Scalars['Int'],
+  rounds?: Maybe<Scalars['Int']>,
+  variation?: Maybe<Scalars['String']>,
 };
 
-export type BlockCreatepicturesInput = {
-  set?: Maybe<Array<Scalars['String']>>,
+export type BlockInstanceCreateInput = {
+  id?: Maybe<Scalars['ID']>,
+  order: Scalars['Int'],
+  rounds?: Maybe<Scalars['Int']>,
+  variation?: Maybe<Scalars['String']>,
+  block: BlockCreateOneWithoutBlocksInput,
 };
 
-export type BlockCreatevideosInput = {
-  set?: Maybe<Array<Scalars['String']>>,
+export type BlockInstanceCreateManyInput = {
+  create?: Maybe<Array<BlockInstanceCreateInput>>,
+  connect?: Maybe<Array<BlockInstanceWhereUniqueInput>>,
+};
+
+export type BlockInstanceCreateManyWithoutBlockInput = {
+  create?: Maybe<Array<BlockInstanceCreateWithoutBlockInput>>,
+  connect?: Maybe<Array<BlockInstanceWhereUniqueInput>>,
+};
+
+export type BlockInstanceCreateWithoutBlockInput = {
+  id?: Maybe<Scalars['ID']>,
+  order: Scalars['Int'],
+  rounds?: Maybe<Scalars['Int']>,
+  variation?: Maybe<Scalars['String']>,
+};
+
+export enum BlockInstanceOrderByInput {
+  IdAsc = 'id_ASC',
+  IdDesc = 'id_DESC',
+  OrderAsc = 'order_ASC',
+  OrderDesc = 'order_DESC',
+  RoundsAsc = 'rounds_ASC',
+  RoundsDesc = 'rounds_DESC',
+  VariationAsc = 'variation_ASC',
+  VariationDesc = 'variation_DESC'
+}
+
+export type BlockInstanceWhereInput = {
+  /** Logical AND on all given filters. */
+  AND?: Maybe<Array<BlockInstanceWhereInput>>,
+  /** Logical OR on all given filters. */
+  OR?: Maybe<Array<BlockInstanceWhereInput>>,
+  /** Logical NOT on all given filters combined by AND. */
+  NOT?: Maybe<Array<BlockInstanceWhereInput>>,
+  id?: Maybe<Scalars['ID']>,
+  /** All values that are not equal to given value. */
+  id_not?: Maybe<Scalars['ID']>,
+  /** All values that are contained in given list. */
+  id_in?: Maybe<Array<Scalars['ID']>>,
+  /** All values that are not contained in given list. */
+  id_not_in?: Maybe<Array<Scalars['ID']>>,
+  /** All values less than the given value. */
+  id_lt?: Maybe<Scalars['ID']>,
+  /** All values less than or equal the given value. */
+  id_lte?: Maybe<Scalars['ID']>,
+  /** All values greater than the given value. */
+  id_gt?: Maybe<Scalars['ID']>,
+  /** All values greater than or equal the given value. */
+  id_gte?: Maybe<Scalars['ID']>,
+  /** All values containing the given string. */
+  id_contains?: Maybe<Scalars['ID']>,
+  /** All values not containing the given string. */
+  id_not_contains?: Maybe<Scalars['ID']>,
+  /** All values starting with the given string. */
+  id_starts_with?: Maybe<Scalars['ID']>,
+  /** All values not starting with the given string. */
+  id_not_starts_with?: Maybe<Scalars['ID']>,
+  /** All values ending with the given string. */
+  id_ends_with?: Maybe<Scalars['ID']>,
+  /** All values not ending with the given string. */
+  id_not_ends_with?: Maybe<Scalars['ID']>,
+  order?: Maybe<Scalars['Int']>,
+  /** All values that are not equal to given value. */
+  order_not?: Maybe<Scalars['Int']>,
+  /** All values that are contained in given list. */
+  order_in?: Maybe<Array<Scalars['Int']>>,
+  /** All values that are not contained in given list. */
+  order_not_in?: Maybe<Array<Scalars['Int']>>,
+  /** All values less than the given value. */
+  order_lt?: Maybe<Scalars['Int']>,
+  /** All values less than or equal the given value. */
+  order_lte?: Maybe<Scalars['Int']>,
+  /** All values greater than the given value. */
+  order_gt?: Maybe<Scalars['Int']>,
+  /** All values greater than or equal the given value. */
+  order_gte?: Maybe<Scalars['Int']>,
+  rounds?: Maybe<Scalars['Int']>,
+  /** All values that are not equal to given value. */
+  rounds_not?: Maybe<Scalars['Int']>,
+  /** All values that are contained in given list. */
+  rounds_in?: Maybe<Array<Scalars['Int']>>,
+  /** All values that are not contained in given list. */
+  rounds_not_in?: Maybe<Array<Scalars['Int']>>,
+  /** All values less than the given value. */
+  rounds_lt?: Maybe<Scalars['Int']>,
+  /** All values less than or equal the given value. */
+  rounds_lte?: Maybe<Scalars['Int']>,
+  /** All values greater than the given value. */
+  rounds_gt?: Maybe<Scalars['Int']>,
+  /** All values greater than or equal the given value. */
+  rounds_gte?: Maybe<Scalars['Int']>,
+  variation?: Maybe<Scalars['String']>,
+  /** All values that are not equal to given value. */
+  variation_not?: Maybe<Scalars['String']>,
+  /** All values that are contained in given list. */
+  variation_in?: Maybe<Array<Scalars['String']>>,
+  /** All values that are not contained in given list. */
+  variation_not_in?: Maybe<Array<Scalars['String']>>,
+  /** All values less than the given value. */
+  variation_lt?: Maybe<Scalars['String']>,
+  /** All values less than or equal the given value. */
+  variation_lte?: Maybe<Scalars['String']>,
+  /** All values greater than the given value. */
+  variation_gt?: Maybe<Scalars['String']>,
+  /** All values greater than or equal the given value. */
+  variation_gte?: Maybe<Scalars['String']>,
+  /** All values containing the given string. */
+  variation_contains?: Maybe<Scalars['String']>,
+  /** All values not containing the given string. */
+  variation_not_contains?: Maybe<Scalars['String']>,
+  /** All values starting with the given string. */
+  variation_starts_with?: Maybe<Scalars['String']>,
+  /** All values not starting with the given string. */
+  variation_not_starts_with?: Maybe<Scalars['String']>,
+  /** All values ending with the given string. */
+  variation_ends_with?: Maybe<Scalars['String']>,
+  /** All values not ending with the given string. */
+  variation_not_ends_with?: Maybe<Scalars['String']>,
+  block?: Maybe<BlockWhereInput>,
+};
+
+export type BlockInstanceWhereUniqueInput = {
+  id?: Maybe<Scalars['ID']>,
 };
 
 export enum BlockOrderByInput {
   IdAsc = 'id_ASC',
   IdDesc = 'id_DESC',
-  SequenceAsc = 'sequence_ASC',
-  SequenceDesc = 'sequence_DESC',
   TitleAsc = 'title_ASC',
   TitleDesc = 'title_DESC',
   DescriptionAsc = 'description_ASC',
   DescriptionDesc = 'description_DESC',
   DurationAsc = 'duration_ASC',
   DurationDesc = 'duration_DESC',
-  RoundsAsc = 'rounds_ASC',
-  RoundsDesc = 'rounds_DESC',
   RestAsc = 'rest_ASC',
   RestDesc = 'rest_DESC'
 }
@@ -143,21 +276,6 @@ export type BlockWhereInput = {
   id_ends_with?: Maybe<Scalars['ID']>,
   /** All values not ending with the given string. */
   id_not_ends_with?: Maybe<Scalars['ID']>,
-  sequence?: Maybe<Scalars['Int']>,
-  /** All values that are not equal to given value. */
-  sequence_not?: Maybe<Scalars['Int']>,
-  /** All values that are contained in given list. */
-  sequence_in?: Maybe<Array<Scalars['Int']>>,
-  /** All values that are not contained in given list. */
-  sequence_not_in?: Maybe<Array<Scalars['Int']>>,
-  /** All values less than the given value. */
-  sequence_lt?: Maybe<Scalars['Int']>,
-  /** All values less than or equal the given value. */
-  sequence_lte?: Maybe<Scalars['Int']>,
-  /** All values greater than the given value. */
-  sequence_gt?: Maybe<Scalars['Int']>,
-  /** All values greater than or equal the given value. */
-  sequence_gte?: Maybe<Scalars['Int']>,
   title?: Maybe<Scalars['String']>,
   /** All values that are not equal to given value. */
   title_not?: Maybe<Scalars['String']>,
@@ -227,21 +345,6 @@ export type BlockWhereInput = {
   duration_gt?: Maybe<Scalars['Int']>,
   /** All values greater than or equal the given value. */
   duration_gte?: Maybe<Scalars['Int']>,
-  rounds?: Maybe<Scalars['Int']>,
-  /** All values that are not equal to given value. */
-  rounds_not?: Maybe<Scalars['Int']>,
-  /** All values that are contained in given list. */
-  rounds_in?: Maybe<Array<Scalars['Int']>>,
-  /** All values that are not contained in given list. */
-  rounds_not_in?: Maybe<Array<Scalars['Int']>>,
-  /** All values less than the given value. */
-  rounds_lt?: Maybe<Scalars['Int']>,
-  /** All values less than or equal the given value. */
-  rounds_lte?: Maybe<Scalars['Int']>,
-  /** All values greater than the given value. */
-  rounds_gt?: Maybe<Scalars['Int']>,
-  /** All values greater than or equal the given value. */
-  rounds_gte?: Maybe<Scalars['Int']>,
   rest?: Maybe<Scalars['Int']>,
   /** All values that are not equal to given value. */
   rest_not?: Maybe<Scalars['Int']>,
@@ -261,9 +364,9 @@ export type BlockWhereInput = {
   tracks_every?: Maybe<TrackWhereInput>,
   tracks_some?: Maybe<TrackWhereInput>,
   tracks_none?: Maybe<TrackWhereInput>,
-  blocks_every?: Maybe<BlockWhereInput>,
-  blocks_some?: Maybe<BlockWhereInput>,
-  blocks_none?: Maybe<BlockWhereInput>,
+  blocks_every?: Maybe<BlockInstanceWhereInput>,
+  blocks_some?: Maybe<BlockInstanceWhereInput>,
+  blocks_none?: Maybe<BlockInstanceWhereInput>,
   exercises_every?: Maybe<ExerciseInstanceWhereInput>,
   exercises_some?: Maybe<ExerciseInstanceWhereInput>,
   exercises_none?: Maybe<ExerciseInstanceWhereInput>,
@@ -501,7 +604,8 @@ export type Exercise = Node & {
   id: Scalars['ID'],
   name: Scalars['String'],
   description: Scalars['String'],
-  video: Scalars['String'],
+  videos: Array<Scalars['String']>,
+  pictures: Array<Scalars['String']>,
   targets: Array<Scalars['String']>,
   baseExercise: Array<Scalars['String']>,
 };
@@ -514,7 +618,8 @@ export type ExerciseCreateInput = {
   id?: Maybe<Scalars['ID']>,
   name: Scalars['String'],
   description: Scalars['String'],
-  video: Scalars['String'],
+  videos?: Maybe<ExerciseCreatevideosInput>,
+  pictures?: Maybe<ExerciseCreatepicturesInput>,
   targets?: Maybe<ExerciseCreatetargetsInput>,
   baseExercise?: Maybe<ExerciseCreatebaseExerciseInput>,
 };
@@ -524,19 +629,31 @@ export type ExerciseCreateOneInput = {
   connect?: Maybe<ExerciseWhereUniqueInput>,
 };
 
+export type ExerciseCreatepicturesInput = {
+  set?: Maybe<Array<Scalars['String']>>,
+};
+
 export type ExerciseCreatetargetsInput = {
   set?: Maybe<Array<Scalars['String']>>,
 };
 
+export type ExerciseCreatevideosInput = {
+  set?: Maybe<Array<Scalars['String']>>,
+};
+
 export type ExerciseInstance = Node & {
   id: Scalars['ID'],
   exercise: Exercise,
+  order: Scalars['Int'],
   repetitions?: Maybe<Scalars['Int']>,
+  variation?: Maybe<Scalars['String']>,
 };
 
 export type ExerciseInstanceCreateInput = {
   id?: Maybe<Scalars['ID']>,
+  order: Scalars['Int'],
   repetitions?: Maybe<Scalars['Int']>,
+  variation?: Maybe<Scalars['String']>,
   exercise: ExerciseCreateOneInput,
 };
 
@@ -548,8 +665,12 @@ export type ExerciseInstanceCreateManyInput = {
 export enum ExerciseInstanceOrderByInput {
   IdAsc = 'id_ASC',
   IdDesc = 'id_DESC',
+  OrderAsc = 'order_ASC',
+  OrderDesc = 'order_DESC',
   RepetitionsAsc = 'repetitions_ASC',
-  RepetitionsDesc = 'repetitions_DESC'
+  RepetitionsDesc = 'repetitions_DESC',
+  VariationAsc = 'variation_ASC',
+  VariationDesc = 'variation_DESC'
 }
 
 export type ExerciseInstanceWhereInput = {
@@ -586,6 +707,21 @@ export type ExerciseInstanceWhereInput = {
   id_ends_with?: Maybe<Scalars['ID']>,
   /** All values not ending with the given string. */
   id_not_ends_with?: Maybe<Scalars['ID']>,
+  order?: Maybe<Scalars['Int']>,
+  /** All values that are not equal to given value. */
+  order_not?: Maybe<Scalars['Int']>,
+  /** All values that are contained in given list. */
+  order_in?: Maybe<Array<Scalars['Int']>>,
+  /** All values that are not contained in given list. */
+  order_not_in?: Maybe<Array<Scalars['Int']>>,
+  /** All values less than the given value. */
+  order_lt?: Maybe<Scalars['Int']>,
+  /** All values less than or equal the given value. */
+  order_lte?: Maybe<Scalars['Int']>,
+  /** All values greater than the given value. */
+  order_gt?: Maybe<Scalars['Int']>,
+  /** All values greater than or equal the given value. */
+  order_gte?: Maybe<Scalars['Int']>,
   repetitions?: Maybe<Scalars['Int']>,
   /** All values that are not equal to given value. */
   repetitions_not?: Maybe<Scalars['Int']>,
@@ -601,6 +737,33 @@ export type ExerciseInstanceWhereInput = {
   repetitions_gt?: Maybe<Scalars['Int']>,
   /** All values greater than or equal the given value. */
   repetitions_gte?: Maybe<Scalars['Int']>,
+  variation?: Maybe<Scalars['String']>,
+  /** All values that are not equal to given value. */
+  variation_not?: Maybe<Scalars['String']>,
+  /** All values that are contained in given list. */
+  variation_in?: Maybe<Array<Scalars['String']>>,
+  /** All values that are not contained in given list. */
+  variation_not_in?: Maybe<Array<Scalars['String']>>,
+  /** All values less than the given value. */
+  variation_lt?: Maybe<Scalars['String']>,
+  /** All values less than or equal the given value. */
+  variation_lte?: Maybe<Scalars['String']>,
+  /** All values greater than the given value. */
+  variation_gt?: Maybe<Scalars['String']>,
+  /** All values greater than or equal the given value. */
+  variation_gte?: Maybe<Scalars['String']>,
+  /** All values containing the given string. */
+  variation_contains?: Maybe<Scalars['String']>,
+  /** All values not containing the given string. */
+  variation_not_contains?: Maybe<Scalars['String']>,
+  /** All values starting with the given string. */
+  variation_starts_with?: Maybe<Scalars['String']>,
+  /** All values not starting with the given string. */
+  variation_not_starts_with?: Maybe<Scalars['String']>,
+  /** All values ending with the given string. */
+  variation_ends_with?: Maybe<Scalars['String']>,
+  /** All values not ending with the given string. */
+  variation_not_ends_with?: Maybe<Scalars['String']>,
   exercise?: Maybe<ExerciseWhereInput>,
 };
 
@@ -608,6 +771,15 @@ export type ExerciseInstanceWhereUniqueInput = {
   id?: Maybe<Scalars['ID']>,
 };
 
+export enum ExerciseOrderByInput {
+  IdAsc = 'id_ASC',
+  IdDesc = 'id_DESC',
+  NameAsc = 'name_ASC',
+  NameDesc = 'name_DESC',
+  DescriptionAsc = 'description_ASC',
+  DescriptionDesc = 'description_DESC'
+}
+
 export type ExerciseWhereInput = {
   /** Logical AND on all given filters. */
   AND?: Maybe<Array<ExerciseWhereInput>>,
@@ -696,33 +868,6 @@ export type ExerciseWhereInput = {
   description_ends_with?: Maybe<Scalars['String']>,
   /** All values not ending with the given string. */
   description_not_ends_with?: Maybe<Scalars['String']>,
-  video?: Maybe<Scalars['String']>,
-  /** All values that are not equal to given value. */
-  video_not?: Maybe<Scalars['String']>,
-  /** All values that are contained in given list. */
-  video_in?: Maybe<Array<Scalars['String']>>,
-  /** All values that are not contained in given list. */
-  video_not_in?: Maybe<Array<Scalars['String']>>,
-  /** All values less than the given value. */
-  video_lt?: Maybe<Scalars['String']>,
-  /** All values less than or equal the given value. */
-  video_lte?: Maybe<Scalars['String']>,
-  /** All values greater than the given value. */
-  video_gt?: Maybe<Scalars['String']>,
-  /** All values greater than or equal the given value. */
-  video_gte?: Maybe<Scalars['String']>,
-  /** All values containing the given string. */
-  video_contains?: Maybe<Scalars['String']>,
-  /** All values not containing the given string. */
-  video_not_contains?: Maybe<Scalars['String']>,
-  /** All values starting with the given string. */
-  video_starts_with?: Maybe<Scalars['String']>,
-  /** All values not starting with the given string. */
-  video_not_starts_with?: Maybe<Scalars['String']>,
-  /** All values ending with the given string. */
-  video_ends_with?: Maybe<Scalars['String']>,
-  /** All values not ending with the given string. */
-  video_not_ends_with?: Maybe<Scalars['String']>,
 };
 
 export type ExerciseWhereUniqueInput = {
@@ -885,10 +1030,10 @@ export type MutationCreateTrainingArgs = {
   title: Scalars['String'],
   type: TrainingTypeCreateOneInput,
   trainingDate: Scalars['DateTime'],
-  location: Scalars['String'],
-  attendance: Scalars['Int'],
+  location?: Maybe<Scalars['String']>,
+  attendance?: Maybe<Scalars['Int']>,
   published: Scalars['Boolean'],
-  blocks?: Maybe<BlockCreateManyInput>
+  blocks?: Maybe<BlockInstanceCreateManyInput>
 };
 
 
@@ -899,14 +1044,16 @@ export type MutationCreateTrainingTypeArgs = {
 
 
 export type MutationCreateBlockArgs = {
-  sequence: Scalars['Int'],
   title: Scalars['String'],
-  duration: Scalars['Int'],
-  variation?: Maybe<Scalars['String']>,
-  format?: Maybe<Scalars['ID']>,
-  tracks: Array<Maybe<Scalars['ID']>>,
-  exercises: Array<Maybe<Scalars['ID']>>,
-  description: Scalars['String']
+  description?: Maybe<Scalars['String']>,
+  videos?: Maybe<Array<Scalars['String']>>,
+  pictures?: Maybe<Array<Scalars['String']>>,
+  duration?: Maybe<Scalars['Int']>,
+  format: FormatCreateOneInput,
+  rest?: Maybe<Scalars['Int']>,
+  tracks?: Maybe<TrackCreateManyInput>,
+  blocks?: Maybe<BlockInstanceCreateManyWithoutBlockInput>,
+  exercises?: Maybe<ExerciseInstanceCreateManyInput>
 };
 
 
@@ -951,14 +1098,24 @@ export enum Permission {
 }
 
 export type Query = {
+  currentUser: User,
+  user?: Maybe<User>,
   users: Array<User>,
   training?: Maybe<Training>,
   trainings: Array<Training>,
   trainingType?: Maybe<TrainingType>,
   trainingTypes: Array<TrainingType>,
+  block?: Maybe<Block>,
   blocks: Array<Block>,
+  format?: Maybe<Format>,
   formats: Array<Format>,
-  currentUser: User,
+  exercise?: Maybe<Exercise>,
+  exercises: Array<Exercise>,
+};
+
+
+export type QueryUserArgs = {
+  where: UserWhereUniqueInput
 };
 
 
@@ -974,7 +1131,7 @@ export type QueryUsersArgs = {
 
 
 export type QueryTrainingArgs = {
-  where: TrainingWhereUniqueInput
+  id: Scalars['ID']
 };
 
 
@@ -1005,6 +1162,11 @@ export type QueryTrainingTypesArgs = {
 };
 
 
+export type QueryBlockArgs = {
+  where: BlockWhereUniqueInput
+};
+
+
 export type QueryBlocksArgs = {
   where?: Maybe<BlockWhereInput>,
   orderBy?: Maybe<BlockOrderByInput>,
@@ -1016,6 +1178,11 @@ export type QueryBlocksArgs = {
 };
 
 
+export type QueryFormatArgs = {
+  where: FormatWhereUniqueInput
+};
+
+
 export type QueryFormatsArgs = {
   where?: Maybe<FormatWhereInput>,
   orderBy?: Maybe<FormatOrderByInput>,
@@ -1026,6 +1193,22 @@ export type QueryFormatsArgs = {
   last?: Maybe<Scalars['Int']>
 };
 
+
+export type QueryExerciseArgs = {
+  where: ExerciseWhereUniqueInput
+};
+
+
+export type QueryExercisesArgs = {
+  where?: Maybe<ExerciseWhereInput>,
+  orderBy?: Maybe<ExerciseOrderByInput>,
+  skip?: Maybe<Scalars['Int']>,
+  after?: Maybe<Scalars['String']>,
+  before?: Maybe<Scalars['String']>,
+  first?: Maybe<Scalars['Int']>,
+  last?: Maybe<Scalars['Int']>
+};
+
 export type Rating = Node & {
   id: Scalars['ID'],
   user: User,
@@ -1466,7 +1649,7 @@ export type Training = Node & {
   attendance?: Maybe<Scalars['Int']>,
   ratings?: Maybe<Array<Rating>>,
   published: Scalars['Boolean'],
-  blocks?: Maybe<Array<Block>>,
+  blocks?: Maybe<Array<BlockInstance>>,
 };
 
 
@@ -1493,8 +1676,8 @@ export type TrainingRatingsArgs = {
 
 
 export type TrainingBlocksArgs = {
-  where?: Maybe<BlockWhereInput>,
-  orderBy?: Maybe<BlockOrderByInput>,
+  where?: Maybe<BlockInstanceWhereInput>,
+  orderBy?: Maybe<BlockInstanceOrderByInput>,
   skip?: Maybe<Scalars['Int']>,
   after?: Maybe<Scalars['String']>,
   before?: Maybe<Scalars['String']>,
@@ -1783,13 +1966,9 @@ export type TrainingWhereInput = {
   ratings_every?: Maybe<RatingWhereInput>,
   ratings_some?: Maybe<RatingWhereInput>,
   ratings_none?: Maybe<RatingWhereInput>,
-  blocks_every?: Maybe<BlockWhereInput>,
-  blocks_some?: Maybe<BlockWhereInput>,
-  blocks_none?: Maybe<BlockWhereInput>,
-};
-
-export type TrainingWhereUniqueInput = {
-  id?: Maybe<Scalars['ID']>,
+  blocks_every?: Maybe<BlockInstanceWhereInput>,
+  blocks_some?: Maybe<BlockInstanceWhereInput>,
+  blocks_none?: Maybe<BlockInstanceWhereInput>,
 };
 
 export type User = Node & {
@@ -2066,6 +2245,21 @@ export type UserWhereInput = {
   ratings_none?: Maybe<RatingWhereInput>,
 };
 
+export type UserWhereUniqueInput = {
+  id?: Maybe<Scalars['ID']>,
+  email?: Maybe<Scalars['String']>,
+};
+
+export type TrainingQueryVariables = {
+  id: Scalars['ID']
+};
+
+
+export type TrainingQuery = { training: Maybe<(
+    Pick<Training, 'id' | 'title' | 'location' | 'trainingDate' | 'attendance' | 'published'>
+    & { type: Pick<TrainingType, 'id'> }
+  )> };
+
 export type TrainingsQueryVariables = {};
 
 
@@ -2098,7 +2292,7 @@ export type CreateTrainingMutationVariables = {
   location: Scalars['String'],
   attendance: Scalars['Int'],
   published: Scalars['Boolean'],
-  blocks?: Maybe<BlockCreateManyInput>
+  blocks?: Maybe<BlockInstanceCreateManyInput>
 };
 
 
@@ -2183,6 +2377,47 @@ export type UserUpdateMutationVariables = {
 export type UserUpdateMutation = { updateUser: Maybe<Pick<User, 'id' | 'name' | 'email' | 'permissions' | 'interests'>> };
 
 
+export const TrainingDocument = gql`
+    query training($id: ID!) {
+  training(id: $id) {
+    id
+    title
+    type {
+      id
+    }
+    location
+    trainingDate
+    attendance
+    published
+  }
+}
+    `;
+
+/**
+ * __useTrainingQuery__
+ *
+ * To run a query within a React component, call `useTrainingQuery` and pass it any options that fit your needs.
+ * When your component renders, `useTrainingQuery` returns an object from Apollo Client that contains loading, error, and data properties 
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useTrainingQuery({
+ *   variables: {
+ *      id: // value for 'id'
+ *   },
+ * });
+ */
+export function useTrainingQuery(baseOptions?: ApolloReactHooks.QueryHookOptions<TrainingQuery, TrainingQueryVariables>) {
+        return ApolloReactHooks.useQuery<TrainingQuery, TrainingQueryVariables>(TrainingDocument, baseOptions);
+      }
+export function useTrainingLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions<TrainingQuery, TrainingQueryVariables>) {
+          return ApolloReactHooks.useLazyQuery<TrainingQuery, TrainingQueryVariables>(TrainingDocument, baseOptions);
+        }
+export type TrainingQueryHookResult = ReturnType<typeof useTrainingQuery>;
+export type TrainingLazyQueryHookResult = ReturnType<typeof useTrainingLazyQuery>;
+export type TrainingQueryResult = ApolloReactCommon.QueryResult<TrainingQuery, TrainingQueryVariables>;
 export const TrainingsDocument = gql`
     query trainings {
   trainings {
@@ -2329,7 +2564,7 @@ export type FormatsQueryHookResult = ReturnType<typeof useFormatsQuery>;
 export type FormatsLazyQueryHookResult = ReturnType<typeof useFormatsLazyQuery>;
 export type FormatsQueryResult = ApolloReactCommon.QueryResult<FormatsQuery, FormatsQueryVariables>;
 export const CreateTrainingDocument = gql`
-    mutation createTraining($title: String!, $type: TrainingTypeCreateOneInput!, $trainingDate: DateTime!, $location: String!, $attendance: Int!, $published: Boolean!, $blocks: BlockCreateManyInput) {
+    mutation createTraining($title: String!, $type: TrainingTypeCreateOneInput!, $trainingDate: DateTime!, $location: String!, $attendance: Int!, $published: Boolean!, $blocks: BlockInstanceCreateManyInput) {
   createTraining(title: $title, type: $type, trainingDate: $trainingDate, location: $location, attendance: $attendance, published: $published, blocks: $blocks) {
     id
   }

+ 0 - 0
frontend/src/modal/hooks/useModal.ts → frontend/src/lib/subFields.ts


+ 57 - 0
frontend/src/modal/components/Modal.tsx

@@ -0,0 +1,57 @@
+import React, { FunctionComponent, useEffect, useRef } from 'react'
+import { createPortal } from 'react-dom'
+
+interface IModal {
+  state: [boolean, Function]
+  children?: any
+}
+
+const Modal: FunctionComponent<IModal> = ({ state, children }) => {
+  const [visible, setVisible] = state
+  const ref = useRef<undefined | HTMLElement>()
+
+  useEffect(() => {
+    ref.current = document.body
+  }, [])
+
+  const content = visible ? (
+    <div className='modal'>
+      <div className='container'>
+        <button onClick={() => setVisible(false)} className='modal-close'>
+          Close
+        </button>
+        {children}
+      </div>
+      <style jsx>{`
+        .modal {
+          position: absolute;
+          top: 0;
+          left: 0;
+          height: 100vh;
+          width: 100vw;
+          background-color: #000000bb;
+        }
+        .modal > .container {
+          margin: 2em auto;
+          padding: 2em;
+          background-color: #e0e0e0;
+          max-width: 768px;
+          width: 90vw;
+          border-radius: 5px;
+          box-shadow: 0px 0px 5px 5px #77777777;
+        }
+        .modal > .container > button.modal-close {
+          float: right;
+          padding: 0.3em 0.8em;
+          border: none;
+          color: white;
+          background-color: black;
+        }
+      `}</style>
+    </div>
+  ) : null
+
+  return ref.current ? createPortal(content, ref.current) : null
+}
+
+export default Modal

+ 2 - 2
frontend/src/modal/index.ts

@@ -1,3 +1,3 @@
-import { createContext } from "react";
+import Modal from './components/Modal'
 
-export const modalContext = createContext({ visible: true });
+export { Modal }

+ 60 - 0
frontend/src/sortable/components/SortableList.tsx

@@ -0,0 +1,60 @@
+import React, { useState } from 'react'
+import {
+  SortableContainer,
+  SortableElement,
+  SortableHandle
+} from 'react-sortable-hoc'
+import arrayMove from 'array-move'
+
+const DragHandle = SortableHandle(() => (
+  <span>
+    ::
+    <style jsx>{`
+      span {
+        user-select: none;
+      }
+    `}</style>
+  </span>
+))
+
+const SortableItem = SortableElement(({ item }: any) => (
+  <li>
+    <DragHandle />
+    {item}
+  </li>
+))
+
+const SortableList = SortableContainer(({ items }: { items: any[] }) => {
+  return (
+    <ul>
+      {items.map((item: any, index: number) => (
+        <SortableItem key={item} index={index} item={item} />
+      ))}
+    </ul>
+  )
+})
+
+const SortableComponent = ({ items }: { items: any[] }) => {
+  const [state, setState] = useState(items)
+
+  function onSortEnd({
+    oldIndex,
+    newIndex
+  }: {
+    oldIndex: number
+    newIndex: number
+  }) {
+    const a = arrayMove(state, oldIndex, newIndex)
+    setState(a)
+  }
+  return (
+    <SortableList
+      onSortEnd={onSortEnd}
+      items={state}
+      lockAxis='y'
+      useDragHandle={true}
+    />
+  )
+}
+
+export default SortableList

+ 3 - 0
frontend/src/sortable/index.ts

@@ -0,0 +1,3 @@
+import SortableList from './components/SortableList'
+
+export { SortableList }

+ 0 - 0
frontend/src/sortable/utils.ts


+ 64 - 0
frontend/src/training/components/AddTrainingType.tsx

@@ -0,0 +1,64 @@
+import { TextInput, useForm } from '../../form'
+import {
+  useCreateTrainingTypeMutation,
+  TrainingTypesDocument,
+  CreateTrainingTypeMutation
+} from '../../gql'
+import { FetchResult } from '@apollo/client'
+
+const AddTrainingType = ({
+  onSuccess
+}: {
+  onSuccess: (
+    result: FetchResult<
+      CreateTrainingTypeMutation,
+      Record<string, any>,
+      Record<string, any>
+    >
+  ) => void
+}) => {
+  const [
+    createTrainingType,
+    { data, error, loading }
+  ] = useCreateTrainingTypeMutation()
+  const { values, touched, ...props } = useForm({
+    name: '',
+    description: ''
+  })
+
+  return (
+    <form
+      onSubmit={async event => {
+        console.log(event)
+        event.preventDefault()
+        event.stopPropagation()
+        const result = await createTrainingType({
+          variables: values,
+          refetchQueries: [{ query: TrainingTypesDocument }]
+        })
+        if (result.data) onSuccess(result)
+      }}
+    >
+      <h1>Add Training Type</h1>
+      <TextInput name='name' label='Name' value={values.name} {...props} />
+      <TextInput
+        name='description'
+        label='Description'
+        value={values.description}
+        {...props}
+      />
+      <button type='submit'>Save</button>
+      {error && <span className='error'>{error.message}</span>}
+
+      <style jsx>
+        {`
+          form {
+            max-width: 700px;
+          }
+        `}
+      </style>
+    </form>
+  )
+}
+
+export default AddTrainingType

+ 19 - 0
frontend/src/training/components/EditSubBlocks.tsx

@@ -0,0 +1,19 @@
+import { useState } from 'react'
+import { SortableList } from '../../sortable'
+
+const EditSubBlocks = ({
+  name,
+  value,
+  onChange
+}: {
+  name: string
+  value: any
+  onChange: GenericEventHandler
+}) => {
+  console.log(value)
+  const [state, setState] = useState([1, 2, 3])
+
+  return <SortableList items={state} useDragHandle lockAxis={'y'} />
+}
+
+export default EditSubBlocks

+ 41 - 31
frontend/src/training/components/EditTraining.tsx

@@ -1,46 +1,53 @@
 import {
-  useTrainingsQuery,
+  useTrainingQuery,
   useCreateTrainingMutation,
   CreateTrainingMutationVariables,
-  BlockCreateManyInput
+  BlockInstanceCreateManyInput,
+  TrainingTypeCreateOneInput
 } from '../../gql'
 import { useForm, TextInput, Checkbox, DateTimeInput } from '../../form'
-import BlockFormInputs from './BlockFormInputs'
 import TrainingTypeSelector from './TrainingTypeSelector'
+import { parse } from 'date-fns'
+import EditSubBlocks from './EditSubBlocks'
+import { useEffect } from 'react'
 
-const TrainingList = () => {
-  const { data, error, loading } = useTrainingsQuery()
+const nextTuesday = parse('11:45', 'HH:mm', new Date())
+nextTuesday.setDate(
+  nextTuesday.getDate() + ((2 + 7 - nextTuesday.getDay()) % 7)
+)
 
-  return (
-    <ul>
-      {data &&
-        data.trainings.map(training => (
-          <li key={training.id}>{training.id}</li>
-        ))}
-    </ul>
-  )
-}
+const initialData = {
+  title: '',
+  location: '',
+  attendance: 0,
+  trainingDate: nextTuesday.toISOString(),
+  type: { connect: { id: '' } } as TrainingTypeCreateOneInput,
+  blocks: {
+    connect: [],
+    create: []
+  } as BlockInstanceCreateManyInput,
+  published: false
+} as CreateTrainingMutationVariables
+
+const EditTraining = ({ id = '' }: { id?: string }) => {
+  const trainingData = useTrainingQuery({ variables: { id } })
 
-const NewTraining = ({ id }: { id?: string }) => {
-  const { values, touched, ...props } = useForm({
-    title: '',
-    location: '',
-    attendance: 0,
-    trainingDate: new Date().toISOString(),
-    type: { connect: { id: '' } },
-    blocks: { connect: [], create: [] },
-    published: false
-  } as CreateTrainingMutationVariables)
-  console.log(values.trainingDate)
+  const { values, touched, onChange, loadData } = useForm(initialData)
   const [createTraining, createData] = useCreateTrainingMutation()
+  const props = { onChange }
+
+  useEffect(() => {
+    if (trainingData.data && trainingData.data.training)
+      loadData(trainingData.data.training)
+  }, [trainingData])
+  console.log(data)
 
   return (
     <>
-      <TrainingList />
-
       <form
         onSubmit={ev => {
           ev.preventDefault()
+
           createTraining({ variables: values })
         }}
       >
@@ -72,15 +79,18 @@ const NewTraining = ({ id }: { id?: string }) => {
           {...props}
         />
         <label>Blocks</label>
-        {values.blocks &&
+        <EditSubBlocks name='blocks' value={values.blocks} {...props} />
+        {/*values.blocks &&
           values.blocks.map((block, index) => (
             <BlockFormInputs
               key={index}
-              name={`blocks.${index}`}
+              name='blocks'
+              //label='Blocks'
+              //name={`blocks.${index}`}
               value={block}
               {...props}
             />
-          ))}
+          ))*/}
         <button
           onClick={event => {
             event.preventDefault()
@@ -115,4 +125,4 @@ const NewTraining = ({ id }: { id?: string }) => {
   )
 }
 
-export default NewTraining
+export default EditTraining

+ 21 - 1
frontend/src/training/components/TrainingTypeSelector.tsx

@@ -1,4 +1,7 @@
 import { useTrainingTypesQuery, TrainingTypeCreateOneInput } from '../../gql'
+import { Modal } from '../../modal'
+import AddTrainingType from './AddTrainingType'
+import { useState } from 'react'
 
 interface ITrainingTypeSelector {
   value?: TrainingTypeCreateOneInput
@@ -14,6 +17,7 @@ const TrainingTypeSelector = ({
   label = 'Training type',
   ...props
 }: ITrainingTypeSelector) => {
+  const [modalState, setModalState] = useState(false)
   const trainingTypes = useTrainingTypesQuery()
   const id = value && value.connect && value.connect.id
 
@@ -63,11 +67,27 @@ const TrainingTypeSelector = ({
       <button
         type='button'
         onClick={event => {
-          event.preventDefault()
+          setModalState(true)
         }}
       >
         Add type
       </button>
+      <Modal state={[modalState, setModalState]}>
+        <AddTrainingType
+          onSuccess={result => {
+            setModalState(false)
+            if (result.data) {
+              onChange({
+                target: {
+                  type: 'custom',
+                  value: { connect: { id: result.data.createTrainingType.id } },
+                  name
+                }
+              })
+            }
+          }}
+        />
+      </Modal>
     </>
   )
 }

+ 22 - 0
frontend/src/training/components/TrainingsList.tsx

@@ -0,0 +1,22 @@
+import { useTrainingsQuery } from '../../gql'
+import Link from 'next/link'
+
+const TrainingsList = (props: any) => {
+  const { data, error, loading } = useTrainingsQuery()
+  console.log(props)
+
+  return (
+    <ul>
+      {data &&
+        data.trainings.map(training => (
+          <li key={training.id}>
+            <Link href='/training/[id]' as={`/training/${training.id}`}>
+              <a>{training.title}</a>
+            </Link>
+          </li>
+        ))}
+    </ul>
+  )
+}
+
+export default TrainingsList

+ 15 - 1
frontend/src/training/training.graphql

@@ -1,5 +1,19 @@
 # import * from '../../../backend/database/generated/prisma.graphql'
 
+query training($id: ID!) {
+  training(id: $id) {
+    id
+    title
+    type {
+      id
+    }
+    location
+    trainingDate
+    attendance
+    published
+  }
+}
+
 query trainings {
   trainings {
     id
@@ -47,7 +61,7 @@ mutation createTraining(
   $location: String!
   $attendance: Int!
   $published: Boolean!
-  $blocks: BlockCreateManyInput
+  $blocks: BlockInstanceCreateManyInput
 ) {
   createTraining(
     title: $title

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.