generatePageModule function

Future<void> generatePageModule(
  1. String projectPath,
  2. String pageName, {
  3. String? jsonInput,
})

Command used to generate enterprise page modules.

Implementation

Future<void> generatePageModule(
    String projectPath,
    String pageName, {
      String? jsonInput,
    }) async {

  final state = detectStateManagement(projectPath);

  final basePath = p.join(
    projectPath,
    'lib',
    'presentation',
    'pages',
    pageName,
  );

  final modelDir = p.join(basePath, 'model');

  safeCreateDir(basePath);
  safeCreateDir(modelDir);

  final className =
      pageName[0].toUpperCase() + pageName.substring(1);

  if (state == 'bloc') {

    await _ensureBlocInstalled(projectPath);

    final blocDir = p.join(basePath, 'bloc');
    safeCreateDir(blocDir);

    // Bloc
    safeWriteFile(
        p.join(blocDir, '${pageName}_bloc.dart'),
        '''
import 'package:flutter_bloc/flutter_bloc.dart';

import '${pageName}_event.dart';
import '${pageName}_state.dart';

class ${className}Bloc extends Bloc<${className}Event, ${className}State> {

  ${className}Bloc() : super(const ${className}State()) {

    on<${className}Started>((event, emit) async {

      emit(state.copyWith(status: ${className}Status.loading));

      try {

        await Future.delayed(const Duration(seconds: 1));

        emit(state.copyWith(status: ${className}Status.success));

      } catch (e) {

        emit(state.copyWith(
          status: ${className}Status.error,
          message: e.toString(),
        ));

      }

    });

  }

}
''');

    // Event
    safeWriteFile(
        p.join(blocDir, '${pageName}_event.dart'),
        '''
abstract class ${className}Event {}

class ${className}Started extends ${className}Event {}
''');

    // State
    safeWriteFile(
        p.join(blocDir, '${pageName}_state.dart'),
        '''
import 'package:equatable/equatable.dart';

enum ${className}Status {
  initial,
  loading,
  success,
  error
}

class ${className}State extends Equatable {

  final ${className}Status status;
  final String? message;

  const ${className}State({
    this.status = ${className}Status.initial,
    this.message,
  });

  ${className}State copyWith({
    ${className}Status? status,
    String? message,
  }) {
    return ${className}State(
      status: status ?? this.status,
      message: message ?? this.message,
    );
  }

  @override
  List<Object?> get props => [
        status,
        message,
      ];
}
''');

    // Page
    safeWriteFile(
        p.join(basePath, '${pageName}_page.dart'),
        '''
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'bloc/${pageName}_bloc.dart';
import 'bloc/${pageName}_state.dart';
import 'bloc/${pageName}_event.dart';

class ${className}Page extends StatelessWidget {

  const ${className}Page({super.key});

  @override
  Widget build(BuildContext context) {

    return BlocProvider(
      create: (_) => ${className}Bloc()..add(${className}Started()),
      child: Scaffold(
        appBar: AppBar(
          title: const Text("${className}"),
        ),
        body: BlocBuilder<${className}Bloc, ${className}State>(
          builder: (context, state) {

            switch (state.status) {

              case ${className}Status.loading:
                return const Center(
                  child: CircularProgressIndicator(),
                );

              case ${className}Status.success:
                return const Center(
                  child: Text("${className} Loaded"),
                );

              case ${className}Status.error:
                return Center(
                  child: Text(state.message ?? "Error"),
                );

              default:
                return const Center(
                  child: Text("${className} Page"),
                );

            }

          },
        ),
      ),
    );

  }

}
''');

  } else {

    await _ensureRiverpodInstalled(projectPath);

    final providerDir = p.join(basePath, 'provider');
    safeCreateDir(providerDir);

    safeWriteFile(
        p.join(providerDir, '${pageName}_provider.dart'),
        '''
import 'package:flutter_riverpod/flutter_riverpod.dart';

final ${pageName}Provider =
NotifierProvider<${className}Controller, ${className}State>(
  ${className}Controller.new,
);

class ${className}Controller extends Notifier<${className}State> {

  @override
  ${className}State build() {
    return const ${className}State();
  }

  Future<void> load() async {

    state = state.copyWith(loading: true);

    await Future.delayed(const Duration(seconds: 1));

    state = state.copyWith(loading: false);

  }

}

class ${className}State {

  final bool loading;

  const ${className}State({
    this.loading = false,
  });

  ${className}State copyWith({
    bool? loading,
  }) {
    return ${className}State(
      loading: loading ?? this.loading,
    );
  }

}
''');

    safeWriteFile(
        p.join(basePath, '${pageName}_page.dart'),
        '''
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import 'provider/${pageName}_provider.dart';

class ${className}Page extends ConsumerWidget {

  const ${className}Page({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {

    final state = ref.watch(${pageName}Provider);

    return Scaffold(
      appBar: AppBar(
        title: const Text("${className}"),
      ),
      body: Center(
        child: state.loading
            ? const CircularProgressIndicator()
            : ElevatedButton(
                onPressed: () {
                  ref.read(${pageName}Provider.notifier).load();
                },
                child: const Text("Load"),
              ),
      ),
    );

  }

}
''');
  }

  // ===================== MODEL =====================

  final modelPath = p.join(modelDir, '${pageName}_model.dart');

  if (jsonInput != null && jsonInput.isNotEmpty) {

    final modelCode = generateModelFromJson(className, jsonInput);

    /// allow overwrite (API may change)
    File(modelPath).writeAsStringSync(modelCode);

    print('🔄 ${p.basename(modelPath)} updated.');

  } else {

    safeWriteFile(
        modelPath,
        '''
class ${className}Model {

  final String? id;

  ${className}Model({
    this.id,
  });

}
''');

  }

  print('✅ Enterprise page module "$pageName" generated successfully using $state.');
}