Integration Options/Admin Workout Editor

Admin Workout Editor

Embedded view for creating and managing workouts and exercises. As users interact with the editor, your application will receive events that you can handle to trigger custom logic.


Available only for Flutter.


Custom Query Options:

OptionDescription
hidePlansTabHide the plans tab in the dashboard
tabDefault tab: "workouts", "exercises", or "plans"
isSelectableMenuShow select button on cards, triggers `_selected` events

Available Events:


*General Events:*

  • `kinestex_loaded` - Application fully loaded
  • `kinestex_launched` - Successful authentication
  • `error_occurred` - Authentication error

*Exercise Events:*

  • `exercise_opened` - Exercise detail page opened
  • `exercise_selection_opened` - Exercise list page opened
  • `exercise_selected` - Exercise selected from menu
  • `exercise_saved` - Exercise created/updated
  • `exercise_removed` - Exercise removed from workout

*Workout Events:*

  • `workout_opened` - Workout detail page opened
  • `workout_selection_opened` - Workout list page opened
  • `workout_selected` - Workout selected from menu
  • `workout_saved` - Workout created/updated

*Plan Events:*

  • `plan_opened` - Plan detail page opened
  • `plan_selection_opened` - Plan list page opened
  • `plan_selected` - Plan selected from menu
  • `plan_saved` - Plan created/updated
Admin Workout Editor Integration
Create the admin workout editor view for managing workouts and exercises:
1KinesteXAIFramework.createAdminWorkoutEditor(
2  // Use an organization name to differentiate between different orgs.
3  // If you don't plan to use multiple orgs, you can use your company name.
4  organization: "your_organization_name",
5  isShowKinestex: showKinesteX,
6  // OPTIONAL: show/hide content on the admin dashboard
7  customQueries: {
8    "hidePlansTab": true, // will hide the plans tabs in the dashboard
9    "tab": "workouts", // will default to workouts tab. Options: "exercises", "plans"
10    "isSelectableMenu": true // show select Button, triggers _selected events
11  },
12  isLoading: ValueNotifier<bool>(false),
13  onMessageReceived: (message) {
14    handleWebViewMessage(message);
15  },
16)
Complete Example
Full implementation with event handling:
1import 'package:flutter/material.dart';
2import 'package:kinestex_sdk_flutter/kinestex_sdk.dart';
3import 'package:permission_handler/permission_handler.dart';
4
5Future<void> main() async {
6  WidgetsFlutterBinding.ensureInitialized();
7  await KinesteXAIFramework.initialize(
8    apiKey: "your_api_key",
9    companyName: "your_company_name",
10    userId: "your_user_id",
11  );
12  runApp(const MyApp());
13}
14
15class MyApp extends StatefulWidget {
16  const MyApp({super.key});
17
18  
19  State<MyApp> createState() => _MyAppState();
20}
21
22class _MyAppState extends State<MyApp> {
23  
24  void dispose() {
25    disposeKinesteXAIFramework();
26    super.dispose();
27  }
28
29  Future<void> disposeKinesteXAIFramework() async {
30    await KinesteXAIFramework.dispose();
31  }
32
33  
34  Widget build(BuildContext context) {
35    return MaterialApp(
36      title: 'KinesteX Admin Editor',
37      theme: ThemeData(
38        primarySwatch: Colors.blue,
39      ),
40      home: const MyHomePage(),
41    );
42  }
43}
44
45class MyHomePage extends StatefulWidget {
46  const MyHomePage({super.key});
47
48  
49  State<MyHomePage> createState() => _MyHomePageState();
50}
51
52class _MyHomePageState extends State<MyHomePage> {
53  ValueNotifier<bool> showKinesteX = ValueNotifier<bool>(false);
54
55  
56  void initState() {
57    super.initState();
58    _checkCameraPermission();
59  }
60
61  void _checkCameraPermission() async {
62    if (await Permission.camera.request() != PermissionStatus.granted) {
63      _showCameraAccessDeniedAlert();
64    }
65  }
66
67  void _showCameraAccessDeniedAlert() {
68    showDialog(
69      context: context,
70      builder: (BuildContext context) {
71        return AlertDialog(
72          title: const Text("Camera Permission Denied"),
73          content: const Text("Camera access is required for this app to function properly."),
74          actions: <Widget>[
75            TextButton(
76              child: const Text("OK"),
77              onPressed: () => Navigator.of(context).pop(),
78            ),
79          ],
80        );
81      },
82    );
83  }
84
85  void handleWebViewMessage(WebViewMessage message) {
86    if (message is ExitKinestex) {
87      setState(() {
88        showKinesteX.value = false;
89      });
90    } else if (message is WorkoutSaved) {
91      print('Workout saved: ${message.data["workout_id"]}');
92    } else if (message is ExerciseSaved) {
93      print('Exercise saved: ${message.data["exercise_id"]}');
94    } else if (message is WorkoutSelected) {
95      print('Workout selected: ${message.data["workout_title"]}');
96    } else if (message is ExerciseSelected) {
97      print('Exercise selected: ${message.data["exercise_title"]}');
98    } else if (message is PlanSaved) {
99      print('Plan saved: ${message.data["plan_id"]}');
100    } else if (message is ErrorOccurred) {
101      print('Error: ${message.data["error_message"]}');
102    }
103  }
104
105  Widget createAdminWorkoutEditorView() {
106    return Center(
107      child: KinesteXAIFramework.createAdminWorkoutEditor(
108        organization: "your_organization_name",
109        isShowKinestex: showKinesteX,
110        customQueries: {
111          "hidePlansTab": false,
112          "tab": "workouts",
113          "isSelectableMenu": true,
114        },
115        isLoading: ValueNotifier<bool>(false),
116        onMessageReceived: handleWebViewMessage,
117      ),
118    );
119  }
120
121  
122  Widget build(BuildContext context) {
123    return ValueListenableBuilder(
124      valueListenable: showKinesteX,
125      builder: (context, isShowKinesteX, child) {
126        return isShowKinesteX
127            ? SafeArea(
128                child: createAdminWorkoutEditorView(),
129              )
130            : Scaffold(
131                body: Center(
132                  child: ElevatedButton(
133                    style: ElevatedButton.styleFrom(
134                      padding: const EdgeInsets.symmetric(
135                        horizontal: 40,
136                        vertical: 20,
137                      ),
138                      backgroundColor: Colors.green,
139                      shape: RoundedRectangleBorder(
140                        borderRadius: BorderRadius.circular(10),
141                      ),
142                    ),
143                    onPressed: () {
144                      showKinesteX.value = true;
145                    },
146                    child: const Text(
147                      'Open Admin Workout Editor',
148                      style: TextStyle(
149                        fontSize: 20,
150                        fontWeight: FontWeight.bold,
151                        color: Colors.white,
152                      ),
153                    ),
154                  ),
155                ),
156              );
157      },
158    );
159  }
160}

Need Help?

Our team is ready to assist with your integration.

Contact Support
KinesteX

Personal AI Fitness Trainer & Motion Analysis SDK for Health & Fitness Apps

Contacts

hello@kinestex.com

Supported by

AMKM Investments supporting KinesteXin5 Tech
© 2024. All rights reserved. KinesteX
KinesteX TwitterKinesteX Inst