About This Dashboard
Ini adalah personal dashboard berbasis Flutter Web yang berfokus pada
tampilan modern, animasi halus, dan gaya glassmorphism.
Project ini dibuat sebagai eksplorasi UI interaktif dan personal branding
agar terlihat clean, futuristik, dan nyaman dipandang.
import 'dart:ui';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: DashboardPage(),
);
}
}
/* ================= DASHBOARD ================= */
class DashboardPage extends StatefulWidget {
const DashboardPage({super.key});
@override
State createState() => _DashboardPageState();
}
class _DashboardPageState extends State
with SingleTickerProviderStateMixin {
late AnimationController _bgController;
bool tapped = false;
@override
void initState() {
super.initState();
_bgController = AnimationController(
vsync: this,
duration: const Duration(seconds: 10),
)..repeat(reverse: true);
}
@override
void dispose() {
_bgController.dispose();
super.dispose();
}
void goToAbout() {
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: const Duration(milliseconds: 600),
pageBuilder: (_, __, ___) => const AboutPage(),
transitionsBuilder: (_, animation, __, child) {
final slide = Tween(
begin: const Offset(0, 0.15),
end: Offset.zero,
).animate(CurvedAnimation(
parent: animation,
curve: Curves.easeOut,
));
return FadeTransition(
opacity: animation,
child: SlideTransition(position: slide, child: child),
);
},
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: AnimatedBuilder(
animation: _bgController,
builder: (context, child) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color.lerp(
const Color(0xff8E2DE2),
const Color(0xff4A00E0),
_bgController.value)!,
Color.lerp(
const Color(0xff00c6ff),
const Color(0xfff77062),
_bgController.value)!,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: child,
);
},
child: SafeArea(
child: Center(
child: GlassCard(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: () => setState(() => tapped = !tapped),
child: AnimatedScale(
scale: tapped ? 1.1 : 1.0,
duration: const Duration(milliseconds: 300),
child: Container(
width: 90,
height: 90,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white.withOpacity(0.25),
),
child: const Icon(Icons.person,
size: 48, color: Colors.white),
),
),
),
const SizedBox(height: 20),
const Text(
'Muhammad Iqbal',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.white),
),
const SizedBox(height: 6),
const Text(
'Flutter Learner • UI Enthusiast',
style: TextStyle(color: Colors.white70),
),
const SizedBox(height: 30),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
InfoGlass(title: 'Projects', value: '16'),
InfoGlass(title: 'Focus', value: 'UI/UX'),
InfoGlass(title: 'Tools', value: 'Flutter'),
],
),
const SizedBox(height: 30),
ElevatedButton(
onPressed: goToAbout,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white.withOpacity(0.9),
foregroundColor: Colors.deepPurple,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
child: const Padding(
padding:
EdgeInsets.symmetric(horizontal: 28, vertical: 12),
child: Text('Explore About Me'),
),
),
],
),
),
),
),
),
);
}
}
/* ================= ABOUT PAGE ================= */
class AboutPage extends StatefulWidget {
const AboutPage({super.key});
@override
State createState() => _AboutPageState();
}
class _AboutPageState extends State
with SingleTickerProviderStateMixin {
late AnimationController _controller;
final List skills = [
'Flutter',
'UI Design',
'Animations',
'Web & Mobile',
'Clean Code',
];
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1400),
)..forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xff141E30), Color(0xff243B55)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: GlassCard(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'About Me',
style: TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
color: Colors.white),
),
const SizedBox(height: 16),
const Text(
'I am a student who enjoys building modern Flutter apps '
'with smooth animations, clean UI, and thoughtful interactions. '
'My focus is creating experiences that feel simple but premium.',
style: TextStyle(color: Colors.white70, height: 1.6),
),
const SizedBox(height: 28),
// STATS
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
AboutStat(title: 'Experience', value: 'Learning'),
AboutStat(title: 'Projects', value: '5+'),
AboutStat(title: 'Focus', value: 'UI/UX'),
],
),
const SizedBox(height: 28),
// FOCUS
const Text(
'Currently Exploring',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
const Text(
'• Advanced Flutter UI\n'
'• Animations & Transitions\n'
'• Clean and Scalable Layouts',
style: TextStyle(color: Colors.white70, height: 1.6),
),
const SizedBox(height: 28),
// SKILLS
const Text(
'Skills',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
),
const SizedBox(height: 14),
Wrap(
spacing: 12,
runSpacing: 12,
children: List.generate(skills.length, (index) {
final animation = CurvedAnimation(
parent: _controller,
curve: Interval(
(index * 0.12).clamp(0.0, 1.0),
1,
curve: Curves.easeOut,
),
);
return AnimatedSkillChip(
label: skills[index],
animation: animation,
);
}),
),
const SizedBox(height: 30),
Align(
alignment: Alignment.centerRight,
child: TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Back',
style: TextStyle(color: Colors.white)),
),
),
],
),
),
),
),
),
);
}
}
/* ================= COMPONENTS ================= */
class GlassCard extends StatelessWidget {
final Widget child;
const GlassCard({super.key, required this.child});
@override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(30),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 18, sigmaY: 18),
child: Container(
padding: const EdgeInsets.all(28),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.15),
borderRadius: BorderRadius.circular(30),
border:
Border.all(color: Colors.white.withOpacity(0.3)),
),
child: child,
),
),
);
}
}
class InfoGlass extends StatelessWidget {
final String title;
final String value;
const InfoGlass({super.key, required this.title, required this.value});
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 6),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.18),
borderRadius: BorderRadius.circular(20),
),
child: Column(
children: [
Text(value,
style: const TextStyle(
color: Colors.white, fontWeight: FontWeight.bold)),
const SizedBox(height: 6),
Text(title,
style:
const TextStyle(color: Colors.white70, fontSize: 12)),
],
),
);
}
}
class AboutStat extends StatelessWidget {
final String title;
final String value;
const AboutStat({super.key, required this.title, required this.value});
@override
Widget build(BuildContext context) {
return Column(
children: [
Text(value,
style: const TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold)),
const SizedBox(height: 4),
Text(title,
style:
const TextStyle(color: Colors.white70, fontSize: 12)),
],
);
}
}
class AnimatedSkillChip extends StatelessWidget {
final String label;
final Animation animation;
const AnimatedSkillChip(
{super.key, required this.label, required this.animation});
@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: animation,
child: SlideTransition(
position: Tween(
begin: const Offset(0, 0.3),
end: Offset.zero,
).animate(animation),
child: Container(
padding:
const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(20),
),
child:
Text(label, style: const TextStyle(color: Colors.white)),
),
),
);
}
}
Komentar
Posting Komentar