201 lines
5.6 KiB
Dart
201 lines
5.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:resume/services/breakpoints.dart';
|
|
import 'package:resume/services/content_provider.dart';
|
|
import 'package:resume/widgets/content_widget.dart';
|
|
import 'package:resume/widgets/profile.dart';
|
|
import 'package:url_launcher/url_launcher.dart';
|
|
|
|
class LandingPage extends StatefulWidget {
|
|
const LandingPage({super.key});
|
|
|
|
static const String routeName = '/';
|
|
|
|
@override
|
|
State<LandingPage> createState() => _LandingPageState();
|
|
}
|
|
|
|
class _LandingPageState extends State<LandingPage> {
|
|
bool loadingDone = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
|
await ContentProvider.init();
|
|
setState(() => loadingDone = true);
|
|
});
|
|
}
|
|
|
|
double _getMainContentWidth() {
|
|
final width = MediaQuery.of(context).size.width;
|
|
// if (width < Breakpoints.sm) return width;
|
|
if (width < Breakpoints.md) return width * 0.95;
|
|
if (width < Breakpoints.lg) return width * 0.8;
|
|
if (width < Breakpoints.xl) return width * 0.7;
|
|
if (width < Breakpoints.xl2) return width * 0.6;
|
|
return width * 0.5;
|
|
}
|
|
|
|
double _getSidebarWidth() =>
|
|
(MediaQuery.of(context).size.width - _getMainContentWidth()) / 2;
|
|
|
|
Widget _getSideBar() {
|
|
return ContentBox(
|
|
title: 'Fähigkeiten',
|
|
content: ContentProvider.skills,
|
|
contentType: ContentType.skills,
|
|
);
|
|
}
|
|
|
|
Widget _getMainContent() {
|
|
return Column(
|
|
children: [
|
|
ContentBox(
|
|
title: 'Arbeitserfahrung',
|
|
content: ContentProvider.experience,
|
|
contentType: ContentType.experience,
|
|
),
|
|
const Padding(padding: EdgeInsets.only(bottom: 25)),
|
|
ContentBox(
|
|
title: 'Bildungsweg',
|
|
content: ContentProvider.education,
|
|
contentType: ContentType.education,
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildLayout(BuildContext context, BoxConstraints constraints) {
|
|
if (constraints.maxWidth > Breakpoints.xl2) {
|
|
return Stack(
|
|
children: [
|
|
Align(
|
|
alignment: Alignment.topLeft,
|
|
child: SizedBox(
|
|
width: _getSidebarWidth(),
|
|
child: const Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 50),
|
|
child: Profile(),
|
|
),
|
|
),
|
|
),
|
|
Align(
|
|
alignment: Alignment.topRight,
|
|
child: SizedBox(
|
|
width: _getSidebarWidth(),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
|
child: _getSideBar(),
|
|
),
|
|
),
|
|
),
|
|
Center(
|
|
child: SizedBox(
|
|
width: _getMainContentWidth(),
|
|
child: _getMainContent(),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
} else if (constraints.maxWidth > Breakpoints.xl) {
|
|
return Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisSize: MainAxisSize.max,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
children: [
|
|
const Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 50),
|
|
child: Profile(),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
|
child: _getSideBar(),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
SizedBox(
|
|
width: 900,
|
|
child: _getMainContent(),
|
|
),
|
|
const Padding(padding: EdgeInsets.only(right: 50)),
|
|
],
|
|
);
|
|
} else if (constraints.maxWidth > Breakpoints.lg) {
|
|
return Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisSize: MainAxisSize.max,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
Expanded(
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 25),
|
|
child: Column(
|
|
children: [
|
|
const Profile(),
|
|
_getSideBar(),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
SizedBox(
|
|
width: 650,
|
|
child: _getMainContent(),
|
|
),
|
|
const Padding(padding: EdgeInsets.only(right: 25)),
|
|
],
|
|
);
|
|
} else {
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 25),
|
|
child: Column(
|
|
children: [
|
|
const Profile(),
|
|
const Padding(padding: EdgeInsets.only(bottom: 25)),
|
|
_getMainContent(),
|
|
const Padding(padding: EdgeInsets.only(bottom: 25)),
|
|
_getSideBar(),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text('Landing'),
|
|
actions: const [
|
|
TextButton(onPressed: _launchURL, child: Text('Source Code')),
|
|
],
|
|
),
|
|
body: !loadingDone
|
|
? const Center(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.max,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
CircularProgressIndicator(),
|
|
Padding(padding: EdgeInsets.symmetric(vertical: 10)),
|
|
Text('Loading...')
|
|
],
|
|
),
|
|
)
|
|
: SingleChildScrollView(
|
|
child: LayoutBuilder(
|
|
builder: _buildLayout,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
void _launchURL() async {
|
|
final Uri url = Uri.parse('https://git.skup.in/marco/resume');
|
|
await launchUrl(url);
|
|
}
|