Skip to content

Commit 2897f00

Browse files
refactor: extract shared placeholder widget and fix lifecycle
- Create FeatureNotImplementedScreen reusable widget - Simplify GasSensorScreen and DustSensorScreen to use shared widget - Remove redundant didChangeDependencies calls - Keep lifecycle logic only in initState - Reduce code duplication by ~200 lines Addresses mentor feedback on code quality and maintainability
1 parent 7b09993 commit 2897f00

1 file changed

Lines changed: 123 additions & 0 deletions

File tree

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter/services.dart';
3+
import 'package:pslab/l10n/app_localizations.dart';
4+
import 'package:pslab/providers/locator.dart';
5+
import 'package:pslab/view/widgets/common_scaffold_widget.dart';
6+
7+
/// A reusable placeholder widget for features that are not yet implemented.
8+
/// Used to provide consistent UX across multiple placeholder screens.
9+
class FeatureNotImplementedScreen extends StatefulWidget {
10+
final String title;
11+
final String description;
12+
final IconData icon;
13+
final Color accentColor;
14+
15+
const FeatureNotImplementedScreen({
16+
super.key,
17+
required this.title,
18+
required this.description,
19+
required this.icon,
20+
required this.accentColor,
21+
});
22+
23+
@override
24+
State<FeatureNotImplementedScreen> createState() =>
25+
_FeatureNotImplementedScreenState();
26+
}
27+
28+
class _FeatureNotImplementedScreenState extends State<FeatureNotImplementedScreen> {
29+
AppLocalizations appLocalizations = getIt.get<AppLocalizations>();
30+
31+
@override
32+
void initState() {
33+
super.initState();
34+
_setPortraitOrientation();
35+
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
36+
}
37+
38+
void _setPortraitOrientation() {
39+
SystemChrome.setPreferredOrientations([
40+
DeviceOrientation.portraitUp,
41+
DeviceOrientation.portraitDown,
42+
]);
43+
}
44+
45+
@override
46+
Widget build(BuildContext context) {
47+
return CommonScaffold(
48+
title: widget.title,
49+
body: Center(
50+
child: Padding(
51+
padding: const EdgeInsets.all(24.0),
52+
child: Column(
53+
mainAxisAlignment: MainAxisAlignment.center,
54+
children: [
55+
Icon(
56+
widget.icon,
57+
size: 120,
58+
color: Colors.grey.shade400,
59+
),
60+
const SizedBox(height: 32),
61+
Text(
62+
widget.title,
63+
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
64+
fontWeight: FontWeight.bold,
65+
color: Colors.black87,
66+
),
67+
),
68+
const SizedBox(height: 16),
69+
Text(
70+
appLocalizations.screenNotImplemented,
71+
textAlign: TextAlign.center,
72+
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
73+
color: Colors.grey.shade600,
74+
),
75+
),
76+
const SizedBox(height: 24),
77+
Container(
78+
padding: const EdgeInsets.all(16),
79+
decoration: BoxDecoration(
80+
color: widget.accentColor.withOpacity(0.1),
81+
borderRadius: BorderRadius.circular(8),
82+
border: Border.all(color: widget.accentColor.withOpacity(0.3)),
83+
),
84+
child: Column(
85+
children: [
86+
Icon(
87+
Icons.info_outline,
88+
color: widget.accentColor,
89+
size: 32,
90+
),
91+
const SizedBox(height: 8),
92+
Text(
93+
widget.description,
94+
textAlign: TextAlign.center,
95+
style: TextStyle(
96+
color: widget.accentColor,
97+
fontSize: 14,
98+
),
99+
),
100+
],
101+
),
102+
),
103+
const SizedBox(height: 32),
104+
ElevatedButton.icon(
105+
onPressed: () {
106+
Navigator.pop(context);
107+
},
108+
icon: const Icon(Icons.arrow_back),
109+
label: Text(appLocalizations.close),
110+
style: ElevatedButton.styleFrom(
111+
padding: const EdgeInsets.symmetric(
112+
horizontal: 24,
113+
vertical: 12,
114+
),
115+
),
116+
),
117+
],
118+
),
119+
),
120+
),
121+
);
122+
}
123+
}

0 commit comments

Comments
 (0)