• PEMROGRAMAN WEB DINAMIS

    Pengertian web dinamis adalah suatu web yang konten atau isinya dapat berubah-ubah setiap saat. Sebab dalam teknologi pembuatan web dinamis sudah dirancang semudah mungkin bagi pemakai atau user yang menggunakan web tersebut..

  • SIMULASI DAN KOMUNIKASI DIGITAL

    Suatu proses peniruan dalam bentuk visual yang dideskripsikan menyerupai kata, gambar dan grafis..

  • SISTEM KOMPUTER

    Sistem komputer adalah suatu jaringan elektronik yang terdiri dari perangkat lunak dan perangkat keras yang melakukan tugas tertentu (menerima input, memproses input, menyimpan perintah-perintah, dan menyediakan output dalam bentuk informasi). Selain itu dapat pula diartikan sebagai elemen-elemen yang terkait untuk menjalankan suatu aktivitas dengan menggunakan komputer..

  • DASAR DESAIN GRAPIS

    Banyak yang berpikiran kalau desain yang baik adalah yang membutuhkan jam kerja yang banyak, membutuhkan skill tinggi dan aplikasi yang mahal. Ya, memang, tapi sebenarnya desain yang baik adalah desain yang sederhana, yang membuat setiap orang yang melihatnya mudah menangkap maksud dari sebuah bentuk visual tersebut..

  • BASIS DATA

    Pangkalan data atau basis data (bahasa Inggris: database) adalah kumpulan informasi yang disimpan di dalam komputer secara sistematik sehingga dapat diperiksa menggunakan suatu program komputer untuk memperoleh informasi dari basis data tersebut. Perangkat lunak yang digunakan untuk mengelola dan memanggil kueri (query) basis data disebut sistem manajemen basis data (database management system, DBMS). Sistem basis data dipelajari dalam ilmu informasi.

🚀 Bikin Aplikasi Flutter Web Simpel Banget di Zapp.run!

🚀 Bikin Aplikasi Flutter Web Simpel Banget di Zapp.run!


Halo bestie developer pemula! 👋
Kali ini kita bakal ngoding santai bareng Flutter dan nyobain langsung via Zapp.run, jadi kamu nggak perlu install-install ribet dulu. Cocok banget buat kamu yang lagi belajar atau baru kenalan sama Flutter.

Di sini kita akan bikin aplikasi sederhana tapi kece: ada teks sambutan, gambar dari internet, dan tombol yang bisa munculin popup alert. Yuk simak bareng-bareng!


🧠 Apa yang Kita Pelajari?

✅ Cara bikin struktur dasar project Flutter
✅ Menampilkan teks dan gambar dari internet
✅ Menambahkan tombol aksi (button) dan menampilkan dialog (popup)


🧾 Kodingannya Nih!

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Contoh Widget Flutter',
      home: const HomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Demo Widget Flutter'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              'Halo, Flutter Web di Zapp.run!',
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              textAlign: TextAlign.center,
            ),
            const SizedBox(height: 20),
            Image.network(
              'https://images.unsplash.com/photo-1753925449605-ae94dbee88d7?q=80&w=1029&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
              width: 200,
              height: 150,
              fit: BoxFit.cover,
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                showDialog(
                  context: context,
                  builder: (_) => AlertDialog(
                    title: const Text('Tombol Ditekan'),
                    content: const Text('Kamu menekan tombol!'),
                    actions: [
                      TextButton(
                        child: const Text('Tutup'),
                        onPressed: () => Navigator.pop(context),
                      )
                    ],
                  ),
                );
              },
              child: const Text('Tekan Saya'),
            ),
          ],
        ),
      ),
    );
  }
}

📸 Apa yang Ditampilkan?

Teks ucapan selamat datang
Gambar dari internet yang otomatis muncul
Tombol yang kalau diklik akan menampilkan pesan dialog


🔥 Penjelasan Singkat

  • runApp(): Ini pintu masuk utama aplikasi Flutter kita.

  • MaterialApp: Kerangka utama yang ngatur tampilan gaya Material Design.

  • Scaffold: Wadah utama buat halaman, biar tampilannya rapi.

  • AppBar: Bar bagian atas, buat judul halaman.

  • Column: Buat nampilin widget secara vertikal.

  • Image.network(): Nampilin gambar dari URL.

  • ElevatedButton + AlertDialog: Tombol yang bisa munculin popup, bikin app kita interaktif.


🌐 Cobain Sekarang di Zapp.run!

Langsung aja ke: https://zapp.run

  1. Pilih template Flutter

  2. Paste kode di atas

  3. Klik Run ▶

  4. Liat hasilnya di browser. Gampang banget, kan?


🤩 Kesimpulan

Dengan beberapa baris kode, kamu udah bisa bikin aplikasi Flutter web yang punya teks, gambar, dan tombol aksi! Ini jadi langkah awal yang seru buat kamu yang pengen belajar bikin aplikasi mobile atau web pakai Flutter.

Jangan lupa eksplorasi lebih lanjut ya!
Kalau kamu suka postingan ini, share ke temen sekelasmu biar makin banyak yang jago Flutter! 🧑‍💻🔥


Silahkan Gunakan Link ini untuk mencoba aplikasi yang dibuat : https://z21dy06r121dz.zapp.page/#/

Salam : Darsu

Share:

Menghubungkan aplikasi dengan API dan mengambil data eksternal

Untuk praktikum "Menghubungkan aplikasi dengan API dan mengambil data eksternal", aplikasi Dart Flutter yang cocok dan mudah dipahami pemula adalah:


Aplikasi Cuaca (Weather App) Sederhana

Deskripsi: Menampilkan data cuaca dari API eksternal seperti OpenWeatherMap berdasarkan nama kota.

Fitur:

  • Input nama kota

  • Fetch data cuaca via API

  • Tampilkan suhu, cuaca, dan ikon

Konsep yang Dipelajari:

  • HTTP request menggunakan http package

  • Parsing JSON

  • Penggunaan FutureBuilder

  • Penanganan input dan tampilan dinamis


Aplikasi List Berita (News App)

Deskripsi: Menampilkan daftar berita terkini menggunakan API seperti NewsAPI.org.

Fitur:

  • Ambil berita terkini

  • Tampilkan judul, gambar, dan deskripsi

  • Navigasi ke halaman detail berita

Konsep yang Dipelajari:

  • Ambil data list dari API

  • Gunakan ListView builder

  • Navigasi antar halaman


Aplikasi Quote Harian (Random Quote App)

Deskripsi: Menampilkan kutipan (quotes) motivasi secara acak dari API seperti type.fit/api/quotes

Fitur:

  • Tombol "Get New Quote"

  • Tampilkan quote dan author

  • Refresh konten dari API

Konsep yang Dipelajari:

  • HTTP GET

  • Update UI dengan setState

  • Parsing list JSON


Rekomendasi: Mulai dari Aplikasi Cuaca atau Quote

Kenapa?

  • Mudah dipahami 

  • API gratis dan tidak membutuhkan login/token

  • Bisa dikembangkan lebih lanjut (misalnya tambahkan fitur favorit, simpan offline, dll)


Kalau aplikasi Flutter (yang berjalan di Zapp.run) dengan input teks nama kota secara bebas—misalnya: "Cimahi", "New York", "Tokyo", dll—lalu cari koordinatnya (latitude & longitude) secara otomatis, kemudian gunakan itu untuk fetch cuaca dari Open-Meteo API.




✅ CARA MELAKUKANNYA

Gunakan API Geocoding seperti:

🌐 Open-Meteo Geocoding API

URL:

pgsql
https://geocoding-api.open-meteo.com/v1/search?name=NAMA_KOTA

Contoh:

pgsql
https://geocoding-api.open-meteo.com/v1/search?name=Bandung

Respon JSON akan berisi lat & lon dari nama kota tersebut. Setelah itu, kirim permintaan ke API cuaca utama.


💻 KODE FLUTTER (ZAPP.RUN-COMPATIBLE): Input Kota Bebas

dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void main() {
  runApp(const WeatherApp());
}

class WeatherApp extends StatelessWidget {
  const WeatherApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: WeatherScreen(),
    );
  }
}

class WeatherScreen extends StatefulWidget {
  const WeatherScreen({super.key});

  @override
  State<WeatherScreen> createState() => _WeatherScreenState();
}

class _WeatherScreenState extends State<WeatherScreen> {
  String city = "";
  double? temperature;
  String? weatherDesc;
  String? errorMessage;

  Future<void> fetchWeather(String cityName) async {
    setState(() {
      errorMessage = null;
    });

    final geoUrl =
        'https://geocoding-api.open-meteo.com/v1/search?name=$cityName&count=1';
    final geoRes = await http.get(Uri.parse(geoUrl));

    if (geoRes.statusCode == 200) {
      final geoData = jsonDecode(geoRes.body);

      if (geoData['results'] != null && geoData['results'].isNotEmpty) {
        final lat = geoData['results'][0]['latitude'];
        final lon = geoData['results'][0]['longitude'];
        final resolvedName = geoData['results'][0]['name'];

        final weatherUrl =
            'https://api.open-meteo.com/v1/forecast?latitude=$lat&longitude=$lon&current_weather=true';

        final weatherRes = await http.get(Uri.parse(weatherUrl));

        if (weatherRes.statusCode == 200) {
          final weather = jsonDecode(weatherRes.body)['current_weather'];
          setState(() {
            city = resolvedName;
            temperature = weather['temperature'];
            weatherDesc = _getWeatherDescription(weather['weathercode']);
          });
        } else {
          setState(() {
            errorMessage = "Gagal mengambil data cuaca.";
          });
        }
      } else {
        setState(() {
          errorMessage = "Kota tidak ditemukan.";
        });
      }
    } else {
      setState(() {
        errorMessage = "Gagal mencari lokasi.";
      });
    }
  }

  String _getWeatherDescription(int code) {
    switch (code) {
      case 0:
        return 'Cerah';
      case 1:
      case 2:
      case 3:
        return 'Berawan';
      case 45:
      case 48:
        return 'Berkabut';
      case 51:
      case 53:
      case 55:
        return 'Gerimis';
      case 61:
      case 63:
      case 65:
        return 'Hujan';
      case 80:
      case 81:
      case 82:
        return 'Hujan Lebat';
      default:
        return 'Tidak diketahui';
    }
  }

  final _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Cuaca Global")),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          children: [
            TextField(
              controller: _controller,
              decoration: const InputDecoration(
                labelText: 'Masukkan nama kota',
                border: OutlineInputBorder(),
              ),
              onSubmitted: fetchWeather,
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => fetchWeather(_controller.text),
              child: const Text("Cari Cuaca"),
            ),
            const SizedBox(height: 30),
            if (errorMessage != null)
              Text(errorMessage!,
                  style: const TextStyle(color: Colors.red, fontSize: 16))
            else if (temperature != null && weatherDesc != null) ...[
              Text(
                city,
                style: const TextStyle(fontSize: 24),
              ),
              const SizedBox(height: 10),
              Text(
                'Suhu: ${temperature!.toStringAsFixed(1)}°C',
                style: const TextStyle(fontSize: 20),
              ),
              Text(
                'Kondisi: $weatherDesc',
                style: const TextStyle(fontSize: 20),
              ),
            ]
          ],
        ),
      ),
    );
  }
}


✅ Tambahkan di pubspec.yaml

yaml
name: cuaca_app
description: A simple weather app

environment:
  sdk: '>=2.17.0 <3.0.0'

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.6


🔥 Fitur:

Link Demo Aplikasi : https://zmse06vwmsf0.zapp.page/#/
  • Input kota bebas seluruh dunia

  • Opsi fallback jika kota tidak ditemukan

  • Respon cepat karena pakai Open-Meteo & Geocoding resmi


Visit counter For Websites (Jumlah Pengunjung Halaman)


Share:

Informatika Dasar: Software, Hardware, dan Brainware:

Berikut ini adalah artikel blog edukatif tentang Informatika Dasar: Software, Hardware, dan Brainware



🧠💻 Mengenal Software, Hardware, dan Brainware: Fondasi Dasar Dunia Komputer

Ditulis oleh: Darsu — Guru Informatika SMKN 1 Banjar

Dalam dunia teknologi informasi, kita sering mendengar istilah software, hardware, dan brainware. Tiga komponen ini adalah bagian dasar dari sistem komputer yang perlu kita pahami sejak awal belajar informatika. Tanpa salah satu dari mereka, komputer tidak akan bisa bekerja dengan baik.

Yuk, kita bahas satu per satu dengan bahasa yang sederhana dan mudah dipahami!


💻 1. Apa Itu Hardware?

Hardware adalah bagian dari komputer yang bisa kita lihat dan sentuh langsung. Contohnya seperti layar monitor, keyboard, mouse, CPU, printer, speaker, dan lainnya.

Contoh dalam kehidupan sehari-hari:

  • Ketika kamu mengetik tugas di laptop, kamu sedang menggunakan keyboard (hardware).

  • Ketika kamu menonton video, kamu melihatnya lewat monitor (hardware).

Jadi, hardware itu seperti "tubuh" komputer. Tanpa tubuh, komputer tidak punya bentuk fisik.


🧠 2. Apa Itu Software?

Software adalah program atau aplikasi yang berjalan di dalam komputer. Meskipun tidak bisa disentuh, software bisa digunakan dan dilihat tampilannya di layar.

Contoh software yang sering kamu gunakan:

  • Microsoft Word untuk mengetik

  • Google Chrome untuk browsing

  • Game seperti Minecraft atau Mobile Legends

Ada dua jenis software:

  1. Sistem Operasi seperti Windows atau Android

  2. Aplikasi seperti WhatsApp, Excel, Canva, dll.

Software itu seperti "pikiran" komputer. Tanpa software, hardware tidak tahu harus melakukan apa.


👤 3. Apa Itu Brainware?

Brainware adalah orang yang menggunakan komputer. Siapapun yang mengoperasikan komputer, seperti siswa, guru, teknisi, atau programmer, disebut brainware.

Brainware adalah "jiwa" yang menghidupkan semua. Tanpa orang, komputer hanya benda mati.


🔄 Bagaimana Ketiganya Bekerja Sama?

Ketika kamu membuka aplikasi Google Docs di laptop untuk mengerjakan tugas:

  • Kamu (brainware) menggunakan

  • Laptop (hardware) untuk menjalankan

  • Aplikasi Google Docs (software)

Tanpa salah satu dari ketiganya, kegiatan ini tidak bisa dilakukan.


📝 Aktivitas Belajar untuk Siswa

Untuk memperkuat pemahaman, siswa bisa mengisi LKPD (Lembar Kerja Peserta Didik) dan mengikuti kuis singkat seputar materi ini.

Contoh pertanyaan:

  1. Sebutkan 3 contoh hardware yang kamu temui di sekolah!

  2. Apa perbedaan antara software dan hardware?

  3. Siapa saja yang termasuk brainware di lingkungan sekitarmu?


🎯 Kesimpulan

Komponen Pengertian Singkat Contoh
Hardware Bagian fisik komputer CPU, monitor, keyboard
Software Program dalam komputer Word, Chrome, Windows
Brainware Pengguna komputer Siswa, guru, teknisi

Dengan memahami ketiga komponen ini, kamu sudah berada di jalur yang benar dalam belajar dunia teknologi dan informatika!


📌 Ingin Download LKPD atau Slide Presentasi?

Bagi guru atau siswa yang ingin mengunduh versi PDF dari LKPD dan materi presentasi, silakan hubungi penulis atau unduh langsung di [.....diinformasikan selanjutnya....].


Salam Teknologi,
Mari belajar dengan semangat dan terus berkembang!


darsu_smkn1banjar

Visit counter For Websites
Share:

Membangun Aplikasi Jadwal Mengajar Guru dengan Flutter: Praktis, Edukatif, dan Tanpa Ribet Database

Membangun Aplikasi Jadwal Mengajar Guru dengan Flutter: Praktis, Edukatif, dan Tanpa Ribet Database

✨ Pendahuluan

Teknologi hadir untuk mempermudah kehidupan, termasuk dalam dunia pendidikan. Salah satu kebutuhan utama guru adalah mengelola jadwal mengajar secara praktis dan terorganisir. Bagaimana jika kita bisa membuat aplikasi jadwal sendiri, tanpa perlu koneksi internet dan tanpa menggunakan database rumit?

Melalui artikel ini, Bapak/Ibu guru (atau rekan pengajar) akan diajak memahami dan mempraktikkan pembuatan aplikasi jadwal mengajar guru menggunakan Flutter—sebuah framework pemrograman lintas platform yang kini semakin populer, bahkan bisa dijalankan langsung di browser melalui platform seperti Zapp.run atau VS Code + Android Studio.


📱 Apa yang Akan Dibuat?

Aplikasi sederhana namun fungsional, yang memungkinkan pengguna:

  • Menambahkan jadwal mengajar dari Senin hingga Jumat

  • Menginput data seperti nama guru, mapel, kelas, jam masuk & keluar, serta ruangan

  • Menyimpan data secara permanen di memori lokal perangkat menggunakan shared_preferences

  • Menampilkan data per hari dalam tampilan interaktif dan menarik


💡 Mengapa Tanpa Database?

Biasanya, aplikasi membutuhkan database seperti SQLite. Namun, untuk kebutuhan jadwal skala kecil (misalnya satu guru atau satu kelas), kita bisa cukup menggunakan shared_preferences. Ini adalah metode penyimpanan lokal berbasis key–value yang sangat ringan dan cocok untuk pemula.


🛠️ Fitur Utama Aplikasi

Fitur Penjelasan
🔘 Navigasi Hari Jadwal dikategorikan per hari (Senin–Jumat)
➕ Tambah/Edit Jadwal Menginput dan memperbarui data jadwal
🧠 Penyimpanan Otomatis Data tidak hilang meskipun aplikasi ditutup
✏️ CRUD Sederhana Bisa tambah, ubah, dan hapus jadwal dengan mudah
🎨 Tampilan Modern Menggunakan Material Design Flutter

👨‍🏫 Manfaat untuk Guru dan Pembelajaran

  • Sebagai alat bantu pribadi untuk mengatur jadwal mengajar.

  • Sebagai proyek praktikum siswa SMK, khususnya pada jurusan PPLG atau RPL dalam topik pemrograman mobile.

  • Menumbuhkan literasi digital dan pengenalan teknologi berbasis Flutter di lingkungan sekolah.


🧪 Contoh Cuplikan Kode

Untuk menyimpan data ke memori lokal:

void saveData() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  Map<String, String> data = {};
  jadwalPerHari.forEach((hari, list) {
    data[hari] = jsonEncode(list.map((j) => j.toMap()).toList());
  });
  await prefs.setString('jadwal', jsonEncode(data));
}

🔧 Pengembangan Lebih Lanjut

Aplikasi ini masih bisa dikembangkan menjadi lebih kompleks, misalnya:

  • Menambahkan fitur ekspor ke PDF

  • Menggunakan Firebase untuk penyimpanan cloud dan akses banyak pengguna

  • Menambahkan fitur login guru


🎯 Penutup

Dengan memanfaatkan Flutter dan pendekatan sederhana menggunakan shared_preferences, kita bisa membuat aplikasi pendidikan yang praktis dan bermanfaat. Aplikasi ini cocok digunakan oleh guru, tenaga kependidikan, atau bahkan sebagai media pembelajaran bagi peserta didik di SMK.

Mari terus mendorong inovasi digital dalam pendidikan. Jika tidak kita yang memulainya, siapa lagi?


Kode Program :

main.dart

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';

void main() {
  runApp(const JadwalApp());
}

class JadwalApp extends StatelessWidget {
  const JadwalApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Jadwal Mengajar Guru',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const JadwalScreen(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class Jadwal {
  String namaGuru;
  String namaMapel;
  String kelas;
  String jamMulai;
  String jamSelesai;
  String ruangan;

  Jadwal({
    required this.namaGuru,
    required this.namaMapel,
    required this.kelas,
    required this.jamMulai,
    required this.jamSelesai,
    required this.ruangan,
  });

  Map<String, dynamic> toMap() => {
        'namaGuru': namaGuru,
        'namaMapel': namaMapel,
        'kelas': kelas,
        'jamMulai': jamMulai,
        'jamSelesai': jamSelesai,
        'ruangan': ruangan,
      };

  static Jadwal fromMap(Map<String, dynamic> map) => Jadwal(
        namaGuru: map['namaGuru'],
        namaMapel: map['namaMapel'],
        kelas: map['kelas'],
        jamMulai: map['jamMulai'],
        jamSelesai: map['jamSelesai'],
        ruangan: map['ruangan'],
      );
}

class JadwalScreen extends StatefulWidget {
  const JadwalScreen({super.key});

  @override
  State<JadwalScreen> createState() => _JadwalScreenState();
}

class _JadwalScreenState extends State<JadwalScreen> {
  final List<String> hariList = ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat'];
  int currentIndex = 0;
  final PageController _pageController = PageController();

  Map<String, List<Jadwal>> jadwalPerHari = {
    'Senin': [],
    'Selasa': [],
    'Rabu': [],
    'Kamis': [],
    'Jumat': [],
  };

  final _formKey = GlobalKey<FormState>();
  bool isEditing = false;
  int? editingIndex;
  String editingHari = 'Senin';

  final TextEditingController _namaGuru = TextEditingController();
  final TextEditingController _namaMapel = TextEditingController();
  final TextEditingController _kelas = TextEditingController();
  final TextEditingController _jamMulai = TextEditingController();
  final TextEditingController _jamSelesai = TextEditingController();
  final TextEditingController _ruangan = TextEditingController();

  bool showForm = false;

  @override
  void initState() {
    super.initState();
    loadData();
  }

  void saveData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    Map<String, String> data = {};
    jadwalPerHari.forEach((hari, list) {
      data[hari] = jsonEncode(list.map((j) => j.toMap()).toList());
    });
    await prefs.setString('jadwal', jsonEncode(data));
  }

  void loadData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String? rawData = prefs.getString('jadwal');
    if (rawData != null) {
      Map<String, dynamic> data = jsonDecode(rawData);
      data.forEach((hari, list) {
        List decoded = jsonDecode(list);
        jadwalPerHari[hari] = decoded.map((e) => Jadwal.fromMap(e)).toList();
      });
      setState(() {});
    }
  }

  void clearForm() {
    _namaGuru.clear();
    _namaMapel.clear();
    _kelas.clear();
    _jamMulai.clear();
    _jamSelesai.clear();
    _ruangan.clear();
    editingIndex = null;
    editingHari = '';
    isEditing = false;
  }

  Future<void> pickTime(TextEditingController controller) async {
    TimeOfDay? picked =
        await showTimePicker(context: context, initialTime: TimeOfDay.now());
    if (picked != null) {
      controller.text = picked.format(context);
    }
  }

  @override
  Widget build(BuildContext context) {
    String hari = hariList[currentIndex];
    return Scaffold(
      appBar: AppBar(
        title: const Text('Jadwal Mengajar Guru'),
        actions: [
          IconButton(
            icon: Icon(showForm ? Icons.close : Icons.add),
            onPressed: () {
              setState(() {
                showForm = !showForm;
                if (!showForm) {
                  clearForm();
                }
              });
            },
          )
        ],
      ),
      body: Column(
        children: [
          // Tombol Hari
          SizedBox(
            height: 50,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              itemCount: hariList.length,
              itemBuilder: (context, index) => Padding(
                padding: const EdgeInsets.symmetric(horizontal: 6),
                child: ElevatedButton(
                  onPressed: () {
                    setState(() {
                      currentIndex = index;
                    });
                    _pageController.jumpToPage(index);
                  },
                  style: ElevatedButton.styleFrom(
                    backgroundColor: currentIndex == index
                        ? Colors.blue
                        : Colors.grey.shade400,
                  ),
                  child: Text(hariList[index]),
                ),
              ),
            ),
          ),

          if (showForm)
            Padding(
              padding: const EdgeInsets.all(12),
              child: Form(
                key: _formKey,
                child: Column(
                  children: [
                    TextFormField(
                      controller: _namaGuru,
                      decoration: const InputDecoration(
                        labelText: 'Nama Guru',
                        border: OutlineInputBorder(),
                      ),
                    ),
                    const SizedBox(height: 8),
                    TextFormField(
                      controller: _namaMapel,
                      decoration: const InputDecoration(
                        labelText: 'Mata Pelajaran',
                        border: OutlineInputBorder(),
                      ),
                    ),
                    const SizedBox(height: 8),
                    TextFormField(
                      controller: _kelas,
                      decoration: const InputDecoration(
                        labelText: 'Kelas',
                        border: OutlineInputBorder(),
                      ),
                    ),
                    const SizedBox(height: 8),
                    Row(
                      children: [
                        Expanded(
                          child: TextFormField(
                            controller: _jamMulai,
                            readOnly: true,
                            onTap: () => pickTime(_jamMulai),
                            decoration: const InputDecoration(
                              labelText: 'Jam Mulai',
                              border: OutlineInputBorder(),
                            ),
                          ),
                        ),
                        const SizedBox(width: 8),
                        Expanded(
                          child: TextFormField(
                            controller: _jamSelesai,
                            readOnly: true,
                            onTap: () => pickTime(_jamSelesai),
                            decoration: const InputDecoration(
                              labelText: 'Jam Selesai',
                              border: OutlineInputBorder(),
                            ),
                          ),
                        ),
                      ],
                    ),
                    const SizedBox(height: 8),
                    TextFormField(
                      controller: _ruangan,
                      decoration: const InputDecoration(
                        labelText: 'Ruangan',
                        border: OutlineInputBorder(),
                      ),
                    ),
                    const SizedBox(height: 12),
                    ElevatedButton(
                      onPressed: () {
                        if (_formKey.currentState!.validate()) {
                          Jadwal newJadwal = Jadwal(
                            namaGuru: _namaGuru.text,
                            namaMapel: _namaMapel.text,
                            kelas: _kelas.text,
                            jamMulai: _jamMulai.text,
                            jamSelesai: _jamSelesai.text,
                            ruangan: _ruangan.text,
                          );
                          if (isEditing) {
                            jadwalPerHari[editingHari]![editingIndex!] =
                                newJadwal;
                          } else {
                            jadwalPerHari[hari]?.add(newJadwal);
                          }
                          saveData();
                          setState(() {
                            clearForm();
                            showForm = false;
                          });
                        }
                      },
                      child: Text(isEditing ? 'Simpan Edit' : 'Tambah'),
                    ),
                  ],
                ),
              ),
            ),

          Expanded(
            child: PageView.builder(
              controller: _pageController,
              itemCount: hariList.length,
              onPageChanged: (index) {
                setState(() {
                  currentIndex = index;
                });
              },
              itemBuilder: (context, index) {
                String hari = hariList[index];
                return ListView.builder(
                  itemCount: jadwalPerHari[hari]!.length,
                  itemBuilder: (context, i) {
                    Jadwal j = jadwalPerHari[hari]![i];
                    return Card(
                      margin: const EdgeInsets.all(8),
                      child: ListTile(
                        title: Text('${j.namaMapel} - ${j.kelas}'),
                        subtitle: Text(
                            '${j.jamMulai} - ${j.jamSelesai} | ${j.ruangan}\nGuru: ${j.namaGuru}'),
                        isThreeLine: true,
                        trailing: Row(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            IconButton(
                              icon: const Icon(Icons.edit, color: Colors.green),
                              onPressed: () {
                                setState(() {
                                  isEditing = true;
                                  editingIndex = i;
                                  editingHari = hari;
                                  showForm = true;
                                  _namaGuru.text = j.namaGuru;
                                  _namaMapel.text = j.namaMapel;
                                  _kelas.text = j.kelas;
                                  _jamMulai.text = j.jamMulai;
                                  _jamSelesai.text = j.jamSelesai;
                                  _ruangan.text = j.ruangan;
                                });
                              },
                            ),
                            IconButton(
                              icon: const Icon(Icons.delete, color: Colors.red),
                              onPressed: () {
                                setState(() {
                                  jadwalPerHari[hari]!.removeAt(i);
                                  saveData();
                                });
                              },
                            ),
                          ],
                        ),
                      ),
                    );
                  },
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}


pubspec.yaml

name: flutter_app
description: A new Flutter project.

# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1

environment:
  sdk: '>=2.18.2 <3.0.0'

# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.2.2



  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2

dev_dependencies:
  flutter_test:
    sdk: flutter

  # The "flutter_lints" package below contains a set of recommended lints to
  # encourage good coding practices. The lint set provided by the package is
  # activated in the `analysis_options.yaml` file located at the root of your
  # package. See that file for information about deactivating specific lint
  # rules and activating additional ones.
  flutter_lints: ^2.0.0

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter packages.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/assets-and-images/#resolution-aware

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.dev/custom-fonts/#from-packages

Semoga bermanfaat, untuk mencoba silahkan pakai link ini :
https://zh2i067ph2j0.zapp.page/#/

Share:

Blogger Tricks

Blogger Themes