diff --git a/apps/backend/pkg/pb/api/v1/apiv1connect/workouts.connect.go b/apps/backend/pkg/pb/api/v1/apiv1connect/workouts.connect.go index 0e7b486c..54ae6de2 100644 --- a/apps/backend/pkg/pb/api/v1/apiv1connect/workouts.connect.go +++ b/apps/backend/pkg/pb/api/v1/apiv1connect/workouts.connect.go @@ -40,6 +40,8 @@ const ( WorkoutServiceGetProcedure = "/api.v1.WorkoutService/Get" // WorkoutServiceListProcedure is the fully-qualified name of the WorkoutService's List RPC. WorkoutServiceListProcedure = "/api.v1.WorkoutService/List" + // WorkoutServiceDeleteProcedure is the fully-qualified name of the WorkoutService's Delete RPC. + WorkoutServiceDeleteProcedure = "/api.v1.WorkoutService/Delete" ) // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. @@ -48,6 +50,7 @@ var ( workoutServiceCreateMethodDescriptor = workoutServiceServiceDescriptor.Methods().ByName("Create") workoutServiceGetMethodDescriptor = workoutServiceServiceDescriptor.Methods().ByName("Get") workoutServiceListMethodDescriptor = workoutServiceServiceDescriptor.Methods().ByName("List") + workoutServiceDeleteMethodDescriptor = workoutServiceServiceDescriptor.Methods().ByName("Delete") ) // WorkoutServiceClient is a client for the api.v1.WorkoutService service. @@ -55,6 +58,14 @@ type WorkoutServiceClient interface { Create(context.Context, *connect.Request[v1.CreateWorkoutRequest]) (*connect.Response[v1.CreateWorkoutResponse], error) Get(context.Context, *connect.Request[v1.GetWorkoutRequest]) (*connect.Response[v1.GetWorkoutResponse], error) List(context.Context, *connect.Request[v1.ListWorkoutsRequest]) (*connect.Response[v1.ListWorkoutsResponse], error) + // rpc Start(StartWorkoutRequest) returns (StartWorkoutResponse) { + // option (auth) = true; + // } + // + // rpc Finish(FinishWorkoutRequest) returns (FinishWorkoutResponse) { + // option (auth) = true; + // } + Delete(context.Context, *connect.Request[v1.DeleteWorkoutRequest]) (*connect.Response[v1.DeleteWorkoutResponse], error) } // NewWorkoutServiceClient constructs a client for the api.v1.WorkoutService service. By default, it @@ -85,6 +96,12 @@ func NewWorkoutServiceClient(httpClient connect.HTTPClient, baseURL string, opts connect.WithSchema(workoutServiceListMethodDescriptor), connect.WithClientOptions(opts...), ), + delete: connect.NewClient[v1.DeleteWorkoutRequest, v1.DeleteWorkoutResponse]( + httpClient, + baseURL+WorkoutServiceDeleteProcedure, + connect.WithSchema(workoutServiceDeleteMethodDescriptor), + connect.WithClientOptions(opts...), + ), } } @@ -93,6 +110,7 @@ type workoutServiceClient struct { create *connect.Client[v1.CreateWorkoutRequest, v1.CreateWorkoutResponse] get *connect.Client[v1.GetWorkoutRequest, v1.GetWorkoutResponse] list *connect.Client[v1.ListWorkoutsRequest, v1.ListWorkoutsResponse] + delete *connect.Client[v1.DeleteWorkoutRequest, v1.DeleteWorkoutResponse] } // Create calls api.v1.WorkoutService.Create. @@ -110,11 +128,24 @@ func (c *workoutServiceClient) List(ctx context.Context, req *connect.Request[v1 return c.list.CallUnary(ctx, req) } +// Delete calls api.v1.WorkoutService.Delete. +func (c *workoutServiceClient) Delete(ctx context.Context, req *connect.Request[v1.DeleteWorkoutRequest]) (*connect.Response[v1.DeleteWorkoutResponse], error) { + return c.delete.CallUnary(ctx, req) +} + // WorkoutServiceHandler is an implementation of the api.v1.WorkoutService service. type WorkoutServiceHandler interface { Create(context.Context, *connect.Request[v1.CreateWorkoutRequest]) (*connect.Response[v1.CreateWorkoutResponse], error) Get(context.Context, *connect.Request[v1.GetWorkoutRequest]) (*connect.Response[v1.GetWorkoutResponse], error) List(context.Context, *connect.Request[v1.ListWorkoutsRequest]) (*connect.Response[v1.ListWorkoutsResponse], error) + // rpc Start(StartWorkoutRequest) returns (StartWorkoutResponse) { + // option (auth) = true; + // } + // + // rpc Finish(FinishWorkoutRequest) returns (FinishWorkoutResponse) { + // option (auth) = true; + // } + Delete(context.Context, *connect.Request[v1.DeleteWorkoutRequest]) (*connect.Response[v1.DeleteWorkoutResponse], error) } // NewWorkoutServiceHandler builds an HTTP handler from the service implementation. It returns the @@ -141,6 +172,12 @@ func NewWorkoutServiceHandler(svc WorkoutServiceHandler, opts ...connect.Handler connect.WithSchema(workoutServiceListMethodDescriptor), connect.WithHandlerOptions(opts...), ) + workoutServiceDeleteHandler := connect.NewUnaryHandler( + WorkoutServiceDeleteProcedure, + svc.Delete, + connect.WithSchema(workoutServiceDeleteMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) return "/api.v1.WorkoutService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case WorkoutServiceCreateProcedure: @@ -149,6 +186,8 @@ func NewWorkoutServiceHandler(svc WorkoutServiceHandler, opts ...connect.Handler workoutServiceGetHandler.ServeHTTP(w, r) case WorkoutServiceListProcedure: workoutServiceListHandler.ServeHTTP(w, r) + case WorkoutServiceDeleteProcedure: + workoutServiceDeleteHandler.ServeHTTP(w, r) default: http.NotFound(w, r) } @@ -169,3 +208,7 @@ func (UnimplementedWorkoutServiceHandler) Get(context.Context, *connect.Request[ func (UnimplementedWorkoutServiceHandler) List(context.Context, *connect.Request[v1.ListWorkoutsRequest]) (*connect.Response[v1.ListWorkoutsResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("api.v1.WorkoutService.List is not implemented")) } + +func (UnimplementedWorkoutServiceHandler) Delete(context.Context, *connect.Request[v1.DeleteWorkoutRequest]) (*connect.Response[v1.DeleteWorkoutResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("api.v1.WorkoutService.Delete is not implemented")) +} diff --git a/apps/backend/pkg/pb/api/v1/workouts.pb.go b/apps/backend/pkg/pb/api/v1/workouts.pb.go index 70cdd56a..e8cd766d 100644 --- a/apps/backend/pkg/pb/api/v1/workouts.pb.go +++ b/apps/backend/pkg/pb/api/v1/workouts.pb.go @@ -326,6 +326,109 @@ func (x *GetWorkoutResponse) GetWorkout() *Workout { return nil } +// message FinishWorkoutRequest { +// Workout workout = 1 [(buf.validate.field).required = true]; +// } +// +// message FinishWorkoutResponse {} +// +// message GetWorkoutRequest { +// string id = 1 [(buf.validate.field).string.uuid = true]; +// } +// +// message GetWorkoutResponse { +// Workout Workout = 1; +// } +// +// message UpdateWorkoutRequest { +// Workout Workout = 1 [(buf.validate.field).required = true]; +// google.protobuf.FieldMask update_mask = 2; +// } +// +// message UpdateWorkoutResponse { +// Workout Workout = 1; +// } +type DeleteWorkoutRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *DeleteWorkoutRequest) Reset() { + *x = DeleteWorkoutRequest{} + mi := &file_api_v1_workouts_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteWorkoutRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteWorkoutRequest) ProtoMessage() {} + +func (x *DeleteWorkoutRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v1_workouts_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteWorkoutRequest.ProtoReflect.Descriptor instead. +func (*DeleteWorkoutRequest) Descriptor() ([]byte, []int) { + return file_api_v1_workouts_proto_rawDescGZIP(), []int{6} +} + +func (x *DeleteWorkoutRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type DeleteWorkoutResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteWorkoutResponse) Reset() { + *x = DeleteWorkoutResponse{} + mi := &file_api_v1_workouts_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteWorkoutResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteWorkoutResponse) ProtoMessage() {} + +func (x *DeleteWorkoutResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v1_workouts_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteWorkoutResponse.ProtoReflect.Descriptor instead. +func (*DeleteWorkoutResponse) Descriptor() ([]byte, []int) { + return file_api_v1_workouts_proto_rawDescGZIP(), []int{7} +} + type Workout struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -339,7 +442,7 @@ type Workout struct { func (x *Workout) Reset() { *x = Workout{} - mi := &file_api_v1_workouts_proto_msgTypes[6] + mi := &file_api_v1_workouts_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -351,7 +454,7 @@ func (x *Workout) String() string { func (*Workout) ProtoMessage() {} func (x *Workout) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_workouts_proto_msgTypes[6] + mi := &file_api_v1_workouts_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -364,7 +467,7 @@ func (x *Workout) ProtoReflect() protoreflect.Message { // Deprecated: Use Workout.ProtoReflect.Descriptor instead. func (*Workout) Descriptor() ([]byte, []int) { - return file_api_v1_workouts_proto_rawDescGZIP(), []int{6} + return file_api_v1_workouts_proto_rawDescGZIP(), []int{8} } func (x *Workout) GetId() string { @@ -406,7 +509,7 @@ type ExerciseSets struct { func (x *ExerciseSets) Reset() { *x = ExerciseSets{} - mi := &file_api_v1_workouts_proto_msgTypes[7] + mi := &file_api_v1_workouts_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -418,7 +521,7 @@ func (x *ExerciseSets) String() string { func (*ExerciseSets) ProtoMessage() {} func (x *ExerciseSets) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_workouts_proto_msgTypes[7] + mi := &file_api_v1_workouts_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -431,7 +534,7 @@ func (x *ExerciseSets) ProtoReflect() protoreflect.Message { // Deprecated: Use ExerciseSets.ProtoReflect.Descriptor instead. func (*ExerciseSets) Descriptor() ([]byte, []int) { - return file_api_v1_workouts_proto_rawDescGZIP(), []int{7} + return file_api_v1_workouts_proto_rawDescGZIP(), []int{9} } func (x *ExerciseSets) GetExerciseId() string { @@ -459,7 +562,7 @@ type Set struct { func (x *Set) Reset() { *x = Set{} - mi := &file_api_v1_workouts_proto_msgTypes[8] + mi := &file_api_v1_workouts_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -471,7 +574,7 @@ func (x *Set) String() string { func (*Set) ProtoMessage() {} func (x *Set) ProtoReflect() protoreflect.Message { - mi := &file_api_v1_workouts_proto_msgTypes[8] + mi := &file_api_v1_workouts_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -484,7 +587,7 @@ func (x *Set) ProtoReflect() protoreflect.Message { // Deprecated: Use Set.ProtoReflect.Descriptor instead. func (*Set) Descriptor() ([]byte, []int) { - return file_api_v1_workouts_proto_rawDescGZIP(), []int{8} + return file_api_v1_workouts_proto_rawDescGZIP(), []int{10} } func (x *Set) GetWeight() float64 { @@ -550,55 +653,64 @@ var file_api_v1_workouts_proto_rawDesc = []byte{ 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x07, 0x77, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6f, - 0x75, 0x74, 0x52, 0x07, 0x77, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x22, 0xca, 0x01, 0x0a, 0x07, - 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43, - 0x0a, 0x0b, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, - 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0a, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, - 0x64, 0x41, 0x74, 0x12, 0x43, 0x0a, 0x0d, 0x65, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x65, 0x5f, - 0x73, 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x65, 0x53, 0x65, 0x74, 0x73, - 0x42, 0x08, 0xba, 0x48, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x0c, 0x65, 0x78, 0x65, 0x72, - 0x63, 0x69, 0x73, 0x65, 0x53, 0x65, 0x74, 0x73, 0x22, 0x64, 0x0a, 0x0c, 0x45, 0x78, 0x65, 0x72, - 0x63, 0x69, 0x73, 0x65, 0x53, 0x65, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x72, - 0x63, 0x69, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, - 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0a, 0x65, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, - 0x65, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x04, 0x73, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x42, 0x08, - 0xba, 0x48, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x04, 0x73, 0x65, 0x74, 0x73, 0x22, 0x3a, - 0x0a, 0x03, 0x53, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1b, 0x0a, - 0x04, 0x72, 0x65, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x07, 0xba, 0x48, 0x04, - 0x1a, 0x02, 0x28, 0x01, 0x52, 0x04, 0x72, 0x65, 0x70, 0x73, 0x32, 0xea, 0x01, 0x0a, 0x0e, 0x57, - 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4b, 0x0a, - 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x04, 0x88, 0xb5, 0x18, 0x01, 0x12, 0x42, 0x0a, 0x03, 0x47, 0x65, - 0x74, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, - 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, + 0x75, 0x74, 0x52, 0x07, 0x77, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x22, 0x30, 0x0a, 0x14, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x17, 0x0a, + 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xca, 0x01, 0x0a, 0x07, 0x57, 0x6f, 0x72, 0x6b, 0x6f, + 0x75, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, + 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, + 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x0b, 0x66, 0x69, 0x6e, + 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, + 0x01, 0x01, 0x52, 0x0a, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x41, 0x74, 0x12, 0x43, + 0x0a, 0x0d, 0x65, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, + 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x65, 0x53, 0x65, 0x74, 0x73, 0x42, 0x08, 0xba, 0x48, 0x05, + 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x0c, 0x65, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x65, 0x53, + 0x65, 0x74, 0x73, 0x22, 0x64, 0x0a, 0x0c, 0x45, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x65, 0x53, + 0x65, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, + 0x01, 0x01, 0x52, 0x0a, 0x65, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x65, 0x49, 0x64, 0x12, 0x29, + 0x0a, 0x04, 0x73, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x42, 0x08, 0xba, 0x48, 0x05, 0x92, 0x01, + 0x02, 0x08, 0x01, 0x52, 0x04, 0x73, 0x65, 0x74, 0x73, 0x22, 0x3a, 0x0a, 0x03, 0x53, 0x65, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, + 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x07, 0xba, 0x48, 0x04, 0x1a, 0x02, 0x28, 0x01, 0x52, + 0x04, 0x72, 0x65, 0x70, 0x73, 0x32, 0xb7, 0x02, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, + 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4b, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x04, 0x88, 0xb5, 0x18, 0x01, 0x12, 0x42, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x04, 0x88, 0xb5, 0x18, 0x01, 0x12, 0x47, - 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x04, 0x88, 0xb5, 0x18, 0x01, 0x42, 0x94, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x73, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x73, 0x6e, 0x2f, 0x67, 0x65, 0x74, 0x73, 0x74, - 0x72, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, 0x73, 0x2f, 0x62, 0x61, 0x63, 0x6b, - 0x65, 0x6e, 0x64, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x31, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, 0x06, - 0x41, 0x70, 0x69, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x31, 0xe2, - 0x02, 0x12, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x04, 0x88, 0xb5, 0x18, 0x01, 0x12, 0x47, 0x0a, 0x04, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, + 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, + 0x6f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x04, 0x88, 0xb5, + 0x18, 0x01, 0x12, 0x4b, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, + 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x04, 0x88, 0xb5, 0x18, 0x01, 0x42, + 0x94, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x42, 0x0d, + 0x57, 0x6f, 0x72, 0x6b, 0x6f, 0x75, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, + 0x73, 0x6e, 0x2f, 0x67, 0x65, 0x74, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x2f, 0x61, + 0x70, 0x70, 0x73, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x70, 0x6b, 0x67, 0x2f, + 0x70, 0x62, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x31, 0xa2, + 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x31, 0xca, 0x02, + 0x06, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x31, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x41, + 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -613,7 +725,7 @@ func file_api_v1_workouts_proto_rawDescGZIP() []byte { return file_api_v1_workouts_proto_rawDescData } -var file_api_v1_workouts_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_api_v1_workouts_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_api_v1_workouts_proto_goTypes = []any{ (*CreateWorkoutRequest)(nil), // 0: api.v1.CreateWorkoutRequest (*CreateWorkoutResponse)(nil), // 1: api.v1.CreateWorkoutResponse @@ -621,27 +733,31 @@ var file_api_v1_workouts_proto_goTypes = []any{ (*ListWorkoutsResponse)(nil), // 3: api.v1.ListWorkoutsResponse (*GetWorkoutRequest)(nil), // 4: api.v1.GetWorkoutRequest (*GetWorkoutResponse)(nil), // 5: api.v1.GetWorkoutResponse - (*Workout)(nil), // 6: api.v1.Workout - (*ExerciseSets)(nil), // 7: api.v1.ExerciseSets - (*Set)(nil), // 8: api.v1.Set - (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp + (*DeleteWorkoutRequest)(nil), // 6: api.v1.DeleteWorkoutRequest + (*DeleteWorkoutResponse)(nil), // 7: api.v1.DeleteWorkoutResponse + (*Workout)(nil), // 8: api.v1.Workout + (*ExerciseSets)(nil), // 9: api.v1.ExerciseSets + (*Set)(nil), // 10: api.v1.Set + (*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp } var file_api_v1_workouts_proto_depIdxs = []int32{ - 7, // 0: api.v1.CreateWorkoutRequest.exercise_sets:type_name -> api.v1.ExerciseSets - 9, // 1: api.v1.CreateWorkoutRequest.finished_at:type_name -> google.protobuf.Timestamp - 6, // 2: api.v1.ListWorkoutsResponse.workouts:type_name -> api.v1.Workout - 6, // 3: api.v1.GetWorkoutResponse.workout:type_name -> api.v1.Workout - 9, // 4: api.v1.Workout.finished_at:type_name -> google.protobuf.Timestamp - 7, // 5: api.v1.Workout.exercise_sets:type_name -> api.v1.ExerciseSets - 8, // 6: api.v1.ExerciseSets.sets:type_name -> api.v1.Set + 9, // 0: api.v1.CreateWorkoutRequest.exercise_sets:type_name -> api.v1.ExerciseSets + 11, // 1: api.v1.CreateWorkoutRequest.finished_at:type_name -> google.protobuf.Timestamp + 8, // 2: api.v1.ListWorkoutsResponse.workouts:type_name -> api.v1.Workout + 8, // 3: api.v1.GetWorkoutResponse.workout:type_name -> api.v1.Workout + 11, // 4: api.v1.Workout.finished_at:type_name -> google.protobuf.Timestamp + 9, // 5: api.v1.Workout.exercise_sets:type_name -> api.v1.ExerciseSets + 10, // 6: api.v1.ExerciseSets.sets:type_name -> api.v1.Set 0, // 7: api.v1.WorkoutService.Create:input_type -> api.v1.CreateWorkoutRequest 4, // 8: api.v1.WorkoutService.Get:input_type -> api.v1.GetWorkoutRequest 2, // 9: api.v1.WorkoutService.List:input_type -> api.v1.ListWorkoutsRequest - 1, // 10: api.v1.WorkoutService.Create:output_type -> api.v1.CreateWorkoutResponse - 5, // 11: api.v1.WorkoutService.Get:output_type -> api.v1.GetWorkoutResponse - 3, // 12: api.v1.WorkoutService.List:output_type -> api.v1.ListWorkoutsResponse - 10, // [10:13] is the sub-list for method output_type - 7, // [7:10] is the sub-list for method input_type + 6, // 10: api.v1.WorkoutService.Delete:input_type -> api.v1.DeleteWorkoutRequest + 1, // 11: api.v1.WorkoutService.Create:output_type -> api.v1.CreateWorkoutResponse + 5, // 12: api.v1.WorkoutService.Get:output_type -> api.v1.GetWorkoutResponse + 3, // 13: api.v1.WorkoutService.List:output_type -> api.v1.ListWorkoutsResponse + 7, // 14: api.v1.WorkoutService.Delete:output_type -> api.v1.DeleteWorkoutResponse + 11, // [11:15] is the sub-list for method output_type + 7, // [7:11] is the sub-list for method input_type 7, // [7:7] is the sub-list for extension type_name 7, // [7:7] is the sub-list for extension extendee 0, // [0:7] is the sub-list for field type_name @@ -660,7 +776,7 @@ func file_api_v1_workouts_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_v1_workouts_proto_rawDesc, NumEnums: 0, - NumMessages: 9, + NumMessages: 11, NumExtensions: 0, NumServices: 1, }, diff --git a/apps/backend/pkg/repo/repo.go b/apps/backend/pkg/repo/repo.go index 9f99d543..1b8a394f 100644 --- a/apps/backend/pkg/repo/repo.go +++ b/apps/backend/pkg/repo/repo.go @@ -629,3 +629,43 @@ func (r *Repo) GetWorkout(ctx context.Context, opts ...GetWorkoutOpt) (*orm.Work return workout, nil } + +type DeleteWorkoutOpt func() qm.QueryMod + +func DeleteWorkoutWithID(id string) DeleteWorkoutOpt { + return func() qm.QueryMod { + return orm.WorkoutWhere.ID.EQ(id) + } +} + +func DeleteWorkoutWithUserID(userID string) DeleteWorkoutOpt { + return func() qm.QueryMod { + return orm.WorkoutWhere.UserID.EQ(userID) + } +} + +func (r *Repo) DeleteWorkout(ctx context.Context, opts ...DeleteWorkoutOpt) error { + query := []qm.QueryMod{ + qm.Load(orm.WorkoutRels.Sets), + } + for _, opt := range opts { + query = append(query, opt()) + } + + return r.NewTx(ctx, func(tx *Repo) error { + workout, err := orm.Workouts(query...).One(ctx, tx.executor()) + if err != nil { + return fmt.Errorf("workout fetch: %w", err) + } + + if _, err = workout.R.Sets.DeleteAll(ctx, tx.executor()); err != nil { + return fmt.Errorf("workout sets delete: %w", err) + } + + if _, err = workout.Delete(ctx, tx.executor()); err != nil { + return fmt.Errorf("workout delete: %w", err) + } + + return nil + }) +} diff --git a/apps/backend/rpc/v1/workout.go b/apps/backend/rpc/v1/workout.go index 7388200a..4e5c9058 100644 --- a/apps/backend/rpc/v1/workout.go +++ b/apps/backend/rpc/v1/workout.go @@ -115,3 +115,19 @@ func (h *workoutHandler) List(ctx context.Context, req *connect.Request[v1.ListW }, }, nil } + +func (h *workoutHandler) Delete(ctx context.Context, req *connect.Request[v1.DeleteWorkoutRequest]) (*connect.Response[v1.DeleteWorkoutResponse], error) { + log := xcontext.MustExtractLogger(ctx) + userID := xcontext.MustExtractUserID(ctx) + + if err := h.repo.DeleteWorkout(ctx, + repo.DeleteWorkoutWithID(req.Msg.GetId()), + repo.DeleteWorkoutWithUserID(userID), + ); err != nil { + log.Error("failed to delete workout", zap.Error(err)) + return nil, connect.NewError(connect.CodeInternal, nil) + } + + log.Info("workout deleted") + return &connect.Response[v1.DeleteWorkoutResponse]{}, nil +} diff --git a/apps/web/src/pb/api/v1/workouts_connect.ts b/apps/web/src/pb/api/v1/workouts_connect.ts index dba64fff..69107c7a 100644 --- a/apps/web/src/pb/api/v1/workouts_connect.ts +++ b/apps/web/src/pb/api/v1/workouts_connect.ts @@ -3,7 +3,7 @@ /* eslint-disable */ // @ts-nocheck -import { CreateWorkoutRequest, CreateWorkoutResponse, GetWorkoutRequest, GetWorkoutResponse, ListWorkoutsRequest, ListWorkoutsResponse } from "./workouts_pb.js"; +import { CreateWorkoutRequest, CreateWorkoutResponse, DeleteWorkoutRequest, DeleteWorkoutResponse, GetWorkoutRequest, GetWorkoutResponse, ListWorkoutsRequest, ListWorkoutsResponse } from "./workouts_pb.js"; import { MethodKind } from "@bufbuild/protobuf"; /** @@ -39,6 +39,22 @@ export const WorkoutService = { O: ListWorkoutsResponse, kind: MethodKind.Unary, }, + /** + * rpc Start(StartWorkoutRequest) returns (StartWorkoutResponse) { + * option (auth) = true; + * } + * rpc Finish(FinishWorkoutRequest) returns (FinishWorkoutResponse) { + * option (auth) = true; + * } + * + * @generated from rpc api.v1.WorkoutService.Delete + */ + delete: { + name: "Delete", + I: DeleteWorkoutRequest, + O: DeleteWorkoutResponse, + kind: MethodKind.Unary, + }, } } as const; diff --git a/apps/web/src/pb/api/v1/workouts_pb.ts b/apps/web/src/pb/api/v1/workouts_pb.ts index 5e54f331..d28de4ff 100644 --- a/apps/web/src/pb/api/v1/workouts_pb.ts +++ b/apps/web/src/pb/api/v1/workouts_pb.ts @@ -252,6 +252,95 @@ export class GetWorkoutResponse extends Message { } } +/** + * message FinishWorkoutRequest { + * Workout workout = 1 [(buf.validate.field).required = true]; + * } + * message FinishWorkoutResponse {} + * + * message GetWorkoutRequest { + * string id = 1 [(buf.validate.field).string.uuid = true]; + * } + * message GetWorkoutResponse { + * Workout Workout = 1; + * } + * + * message UpdateWorkoutRequest { + * Workout Workout = 1 [(buf.validate.field).required = true]; + * google.protobuf.FieldMask update_mask = 2; + * } + * message UpdateWorkoutResponse { + * Workout Workout = 1; + * } + * + * + * @generated from message api.v1.DeleteWorkoutRequest + */ +export class DeleteWorkoutRequest extends Message { + /** + * @generated from field: string id = 1; + */ + id = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "api.v1.DeleteWorkoutRequest"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "id", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): DeleteWorkoutRequest { + return new DeleteWorkoutRequest().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): DeleteWorkoutRequest { + return new DeleteWorkoutRequest().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): DeleteWorkoutRequest { + return new DeleteWorkoutRequest().fromJsonString(jsonString, options); + } + + static equals(a: DeleteWorkoutRequest | PlainMessage | undefined, b: DeleteWorkoutRequest | PlainMessage | undefined): boolean { + return proto3.util.equals(DeleteWorkoutRequest, a, b); + } +} + +/** + * @generated from message api.v1.DeleteWorkoutResponse + */ +export class DeleteWorkoutResponse extends Message { + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "api.v1.DeleteWorkoutResponse"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): DeleteWorkoutResponse { + return new DeleteWorkoutResponse().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): DeleteWorkoutResponse { + return new DeleteWorkoutResponse().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): DeleteWorkoutResponse { + return new DeleteWorkoutResponse().fromJsonString(jsonString, options); + } + + static equals(a: DeleteWorkoutResponse | PlainMessage | undefined, b: DeleteWorkoutResponse | PlainMessage | undefined): boolean { + return proto3.util.equals(DeleteWorkoutResponse, a, b); + } +} + /** * @generated from message api.v1.Workout */ diff --git a/apps/web/src/views/Auth/UserSignup.vue b/apps/web/src/views/Auth/UserSignup.vue index b107e78a..703a645e 100644 --- a/apps/web/src/views/Auth/UserSignup.vue +++ b/apps/web/src/views/Auth/UserSignup.vue @@ -60,7 +60,14 @@ const signup = async () => {
- +
diff --git a/apps/web/src/views/Workouts/ViewWorkout.vue b/apps/web/src/views/Workouts/ViewWorkout.vue index 39ac1738..e0d9184e 100644 --- a/apps/web/src/views/Workouts/ViewWorkout.vue +++ b/apps/web/src/views/Workouts/ViewWorkout.vue @@ -1,12 +1,13 @@