From a233c844caf1e9b53f35ca01417a7afa9d1aa729 Mon Sep 17 00:00:00 2001 From: akhdanre Date: Sun, 18 May 2025 15:52:33 +0700 Subject: [PATCH] feat: adjust the join room interface --- assets/translations/en-US.json | 5 +- assets/translations/id-ID.json | 6 +- assets/translations/ms-MY.json | 5 +- .../join_room/view/join_room_view.dart | 242 +++++++++++++++--- 4 files changed, 213 insertions(+), 45 deletions(-) diff --git a/assets/translations/en-US.json b/assets/translations/en-US.json index 9eb7d68..06591f6 100644 --- a/assets/translations/en-US.json +++ b/assets/translations/en-US.json @@ -84,5 +84,8 @@ "select_language": "Select Language", "change_language": "Change Language", - "auto_generate_quiz": "Auto Generate Quiz" + "auto_generate_quiz": "Auto Generate Quiz", + "ready_to_compete": "Ready to Compete?", + "enter_code_to_join": "Enter the quiz code and show your skills!", + "join_quiz_now": "Join Quiz Now" } diff --git a/assets/translations/id-ID.json b/assets/translations/id-ID.json index cef3637..8e02cf2 100644 --- a/assets/translations/id-ID.json +++ b/assets/translations/id-ID.json @@ -83,5 +83,9 @@ "select_language": "Pilih Bahasa", "change_language": "Ganti Bahasa", - "auto_generate_quiz": "Buat Kuis Otomatis" + "auto_generate_quiz": "Buat Kuis Otomatis", + + "ready_to_compete": "Siap untuk Bertanding?", + "enter_code_to_join": "Masukkan kode kuis dan tunjukkan kemampuanmu!", + "join_quiz_now": "Gabung Kuis Sekarang" } diff --git a/assets/translations/ms-MY.json b/assets/translations/ms-MY.json index 9cbc487..32eb62f 100644 --- a/assets/translations/ms-MY.json +++ b/assets/translations/ms-MY.json @@ -81,5 +81,8 @@ "make_quiz_public": "Jadikan Kuiz Umum", "save_quiz": "Simpan Kuiz", - "auto_generate_quiz": "Jana Kuiz Automatik" + "auto_generate_quiz": "Jana Kuiz Automatik", + "ready_to_compete": "Bersedia untuk Bertanding?", + "enter_code_to_join": "Masukkan kod kuiz dan tunjukkan kemahiran anda!", + "join_quiz_now": "Sertai Kuiz Sekarang" } diff --git a/lib/feature/join_room/view/join_room_view.dart b/lib/feature/join_room/view/join_room_view.dart index 45103a4..ed3f197 100644 --- a/lib/feature/join_room/view/join_room_view.dart +++ b/lib/feature/join_room/view/join_room_view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:lucide_icons/lucide_icons.dart'; import 'package:quiz_app/app/const/colors/app_colors.dart'; import 'package:quiz_app/component/global_button.dart'; import 'package:quiz_app/component/global_text_field.dart'; @@ -10,59 +11,216 @@ class JoinRoomView extends GetView { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: AppColors.background, + backgroundColor: Colors.white, + // Menggunakan extendBodyBehindAppBar untuk efek lebih menarik + extendBodyBehindAppBar: true, appBar: AppBar( - backgroundColor: AppColors.background, + backgroundColor: Colors.transparent, elevation: 0, leading: IconButton( - icon: const Icon(Icons.arrow_back_ios_new, color: Colors.black87), + icon: const Icon(LucideIcons.arrowLeft, color: Colors.black87), onPressed: () => Get.back(), ), ), - body: SafeArea( - child: Center( + body: Container( + // Background putih bersih + color: Colors.white, + child: SafeArea( child: SingleChildScrollView( - padding: const EdgeInsets.all(24.0), - child: Container( - width: double.infinity, - padding: const EdgeInsets.all(24), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(20), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.06), - blurRadius: 14, - offset: const Offset(0, 6), - ), - ], - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - context.tr("enter_room_code"), - style: const TextStyle( - fontSize: 20, - fontWeight: FontWeight.w700, - color: Colors.black87, + padding: const EdgeInsets.all(24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox(height: 20), + + // Animated Trophy Icon with Hero animation + TweenAnimationBuilder( + duration: const Duration(seconds: 1), + tween: Tween(begin: 0.0, end: 1.0), + builder: (context, value, child) { + return Transform.scale( + scale: value, + child: child, + ); + }, + child: Container( + padding: EdgeInsets.all(22), + decoration: BoxDecoration( + color: AppColors.primaryBlue.withOpacity(0.05), + shape: BoxShape.circle, + border: Border.all( + color: AppColors.primaryBlue.withOpacity(0.15), + width: 2, + ), + ), + child: Icon( + LucideIcons.trophy, + size: 70, + color: AppColors.primaryBlue, ), ), - const SizedBox(height: 16), - GlobalTextField( - controller: controller.codeController, - hintText: context.tr("room_code_hint"), - textInputType: TextInputType.text, - forceUpperCase: true, + ), + + const SizedBox(height: 30), + + // Animated Title + TweenAnimationBuilder( + duration: const Duration(milliseconds: 800), + tween: Tween(begin: 0.0, end: 1.0), + builder: (context, value, child) { + return Opacity( + opacity: value, + child: Transform.translate( + offset: Offset(0, 20 * (1 - value)), + child: child, + ), + ); + }, + child: Text( + context.tr("ready_to_compete"), + style: const TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + color: Colors.black87, + ), + textAlign: TextAlign.center, ), - const SizedBox(height: 30), - GlobalButton( - text: context.tr("join_now"), - onPressed: controller.joinRoom, + ), + + const SizedBox(height: 15), + + // Animated Subtitle + TweenAnimationBuilder( + duration: const Duration(milliseconds: 800), + tween: Tween(begin: 0.0, end: 1.0), + builder: (context, value, child) { + return Opacity( + opacity: value, + child: Transform.translate( + offset: Offset(0, 20 * (1 - value)), + child: child, + ), + ); + }, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Text( + context.tr("enter_code_to_join"), + style: const TextStyle( + fontSize: 16, + color: Colors.black54, + height: 1.4, + ), + textAlign: TextAlign.center, + ), ), - ], - ), + ), + + const SizedBox(height: 40), + + // Animated Card + TweenAnimationBuilder( + duration: const Duration(milliseconds: 1000), + // delay: const Duration(milliseconds: 400), + tween: Tween(begin: 0.0, end: 1.0), + builder: (context, value, child) { + return Opacity( + opacity: value, + child: Transform.translate( + offset: Offset(0, 30 * (1 - value)), + child: child, + ), + ); + }, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 30), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(24), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.08), + blurRadius: 15, + offset: const Offset(0, 5), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + LucideIcons.keySquare, + color: AppColors.primaryBlue, + size: 24, + ), + const SizedBox(width: 12), + Text( + context.tr("enter_room_code"), + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + color: Colors.black87, + ), + ), + ], + ), + const SizedBox(height: 25), + + // Custom text field with better styling + Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + border: Border.all( + color: Colors.grey.shade200, + width: 1, + ), + ), + child: GlobalTextField( + controller: controller.codeController, + hintText: context.tr("room_code_hint"), + textInputType: TextInputType.text, + forceUpperCase: true, + ), + ), + + const SizedBox(height: 30), + + // Button with gradient + GlobalButton( + text: context.tr("join_quiz_now"), + onPressed: controller.joinRoom, + ), + ], + ), + ), + ), + + const SizedBox(height: 30), + + // TweenAnimationBuilder( + // duration: const Duration(milliseconds: 800), + // tween: Tween(begin: 0.0, end: 1.0), + // builder: (context, value, child) { + // return Opacity( + // opacity: value, + // child: child, + // ); + // }, + // child: TextButton( + // onPressed: () {}, + // child: Text( + // context.tr("create_new_room"), + // style: TextStyle( + // color: AppColors.primaryBlue, + // fontWeight: FontWeight.w500, + // ), + // ), + // ), + // ), + ], ), ), ),