Files
tatlock-ui/lib/features/front_hall/presentation/widgets/iframe_view_stub.dart
T
Jeroen SchweitzerandClaude Opus 4.5 40db92d9d5 feat(front-hall): implement three-mode layout with quick links panel
Phase 2 of Organizr Migration - Front Hall restructure:

- Add FrontHallState provider with three modes (dashboard, iframe, settings)
- Create QuickLinksPanel widget with categorized links and overflow menus
- Add IframeView with platform-aware implementation (web iframe, mobile fallback)
- Extract DashboardContent from FrontHallPage
- Add QuickLinkSettingsContent placeholder for Phase 4 link editor
- Implement QuickLink entity and data layer with Core API datasource
- Add default quick links fallback when API unavailable
- Update UI_LAYOUT.md with Front Hall panel configurations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 22:24:20 +01:00

84 lines
2.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
/// Stub implementation for non-web platforms.
///
/// Since iframes are web-only, this shows a message and offers
/// to open the link in an external browser.
class IframeView extends StatelessWidget {
const IframeView({
super.key,
required this.url,
required this.title,
required this.onClose,
});
final String url;
final String title;
final VoidCallback onClose;
Future<void> _openInBrowser() async {
final uri = Uri.tryParse(url);
if (uri != null && await canLaunchUrl(uri)) {
await launchUrl(uri, mode: LaunchMode.externalApplication);
}
}
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final textTheme = Theme.of(context).textTheme;
// Auto-open in browser and show message
WidgetsBinding.instance.addPostFrameCallback((_) {
_openInBrowser();
});
return Center(
child: Padding(
padding: const EdgeInsets.all(32),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.open_in_browser,
size: 64,
color: colorScheme.primary,
),
const SizedBox(height: 16),
Text(
'Opening in Browser',
style: textTheme.titleLarge,
),
const SizedBox(height: 8),
Text(
'Embedded views are not supported on this platform.\n"$title" is opening in your browser.',
textAlign: TextAlign.center,
style: textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurfaceVariant,
),
),
const SizedBox(height: 24),
Row(
mainAxisSize: MainAxisSize.min,
children: [
OutlinedButton.icon(
onPressed: _openInBrowser,
icon: const Icon(Icons.open_in_new),
label: const Text('Open Again'),
),
const SizedBox(width: 12),
FilledButton.icon(
onPressed: onClose,
icon: const Icon(Icons.arrow_back),
label: const Text('Back to Dashboard'),
),
],
),
],
),
),
);
}
}