diff --git a/ExamNETIntermediate/Form1.Designer.cs b/ExamNETIntermediate/Form1.Designer.cs index ece918a..aeeca3e 100644 --- a/ExamNETIntermediate/Form1.Designer.cs +++ b/ExamNETIntermediate/Form1.Designer.cs @@ -28,12 +28,231 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 450); - this.Text = "Form1"; + textBoxTitle = new TextBox(); + textBoxArtist = new TextBox(); + comboBoxGenre = new ComboBox(); + checkBoxIsAvailable = new CheckBox(); + ButtonAdd = new Button(); + ButtonUpdate = new Button(); + ButtonDelete = new Button(); + listBoxSongs = new ListBox(); + label1 = new Label(); + label2 = new Label(); + label3 = new Label(); + label5 = new Label(); + textBoxDetik = new TextBox(); + ButtonUpDetik = new Button(); + ButtonDownDetik = new Button(); + tableLayoutPanel1 = new TableLayoutPanel(); + textBoxSearch = new TextBox(); + tableLayoutPanel1.SuspendLayout(); + SuspendLayout(); + // + // textBoxTitle + // + textBoxTitle.Location = new Point(60, 3); + textBoxTitle.Name = "textBoxTitle"; + textBoxTitle.Size = new Size(125, 27); + textBoxTitle.TabIndex = 0; + // + // textBoxArtist + // + textBoxArtist.Location = new Point(60, 39); + textBoxArtist.Name = "textBoxArtist"; + textBoxArtist.Size = new Size(125, 27); + textBoxArtist.TabIndex = 1; + // + // comboBoxGenre + // + comboBoxGenre.FormattingEnabled = true; + comboBoxGenre.Location = new Point(60, 75); + comboBoxGenre.Name = "comboBoxGenre"; + comboBoxGenre.Size = new Size(143, 28); + comboBoxGenre.TabIndex = 2; + comboBoxGenre.SelectedIndexChanged += comboBoxGenre_SelectedIndexChanged; + // + // checkBoxIsAvailable + // + checkBoxIsAvailable.AutoSize = true; + checkBoxIsAvailable.Location = new Point(60, 107); + checkBoxIsAvailable.Name = "checkBoxIsAvailable"; + checkBoxIsAvailable.Size = new Size(107, 24); + checkBoxIsAvailable.TabIndex = 3; + checkBoxIsAvailable.Text = "Is Available"; + checkBoxIsAvailable.UseVisualStyleBackColor = true; + // + // ButtonAdd + // + ButtonAdd.Location = new Point(209, 3); + ButtonAdd.Name = "ButtonAdd"; + ButtonAdd.Size = new Size(77, 29); + ButtonAdd.TabIndex = 4; + ButtonAdd.Text = "Add"; + ButtonAdd.UseVisualStyleBackColor = true; + ButtonAdd.Click += ButtonAdd_Click; + // + // ButtonUpdate + // + ButtonUpdate.Location = new Point(209, 39); + ButtonUpdate.Name = "ButtonUpdate"; + ButtonUpdate.Size = new Size(77, 29); + ButtonUpdate.TabIndex = 5; + ButtonUpdate.Text = "Update"; + ButtonUpdate.UseVisualStyleBackColor = true; + ButtonUpdate.Click += ButtonUpdate_Click; + // + // ButtonDelete + // + ButtonDelete.Location = new Point(209, 75); + ButtonDelete.Name = "ButtonDelete"; + ButtonDelete.Size = new Size(77, 26); + ButtonDelete.TabIndex = 6; + ButtonDelete.Text = "Delete"; + ButtonDelete.UseVisualStyleBackColor = true; + ButtonDelete.Click += ButtonDelete_Click; + // + // listBoxSongs + // + listBoxSongs.FormattingEnabled = true; + listBoxSongs.Location = new Point(351, 78); + listBoxSongs.Name = "listBoxSongs"; + listBoxSongs.Size = new Size(200, 204); + listBoxSongs.TabIndex = 7; + listBoxSongs.SelectedIndexChanged += listBoxSongs_SelectedIndexChanged; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new Point(3, 0); + label1.Name = "label1"; + label1.Size = new Size(38, 20); + label1.TabIndex = 8; + label1.Text = "Title"; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new Point(3, 36); + label2.Name = "label2"; + label2.Size = new Size(44, 20); + label2.TabIndex = 9; + label2.Text = "Artist"; + // + // label3 + // + label3.AutoSize = true; + label3.Location = new Point(3, 72); + label3.Name = "label3"; + label3.Size = new Size(48, 20); + label3.TabIndex = 10; + label3.Text = "Genre"; + // + // label5 + // + label5.AutoSize = true; + label5.Location = new Point(82, 225); + label5.Name = "label5"; + label5.Size = new Size(44, 20); + label5.TabIndex = 12; + label5.Text = "Detik"; + // + // textBoxDetik + // + textBoxDetik.Location = new Point(82, 248); + textBoxDetik.Name = "textBoxDetik"; + textBoxDetik.Size = new Size(54, 27); + textBoxDetik.TabIndex = 14; + // + // ButtonUpDetik + // + ButtonUpDetik.Location = new Point(58, 281); + ButtonUpDetik.Name = "ButtonUpDetik"; + ButtonUpDetik.Size = new Size(36, 29); + ButtonUpDetik.TabIndex = 17; + ButtonUpDetik.Text = "Up"; + ButtonUpDetik.UseVisualStyleBackColor = true; + // + // ButtonDownDetik + // + ButtonDownDetik.Location = new Point(128, 281); + ButtonDownDetik.Name = "ButtonDownDetik"; + ButtonDownDetik.Size = new Size(61, 29); + ButtonDownDetik.TabIndex = 18; + ButtonDownDetik.Text = "Down"; + ButtonDownDetik.UseVisualStyleBackColor = true; + // + // tableLayoutPanel1 + // + tableLayoutPanel1.ColumnCount = 3; + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 27.61194F)); + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 72.38806F)); + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 82F)); + tableLayoutPanel1.Controls.Add(label1, 0, 0); + tableLayoutPanel1.Controls.Add(label2, 0, 1); + tableLayoutPanel1.Controls.Add(label3, 0, 2); + tableLayoutPanel1.Controls.Add(checkBoxIsAvailable, 1, 3); + tableLayoutPanel1.Controls.Add(textBoxTitle, 1, 0); + tableLayoutPanel1.Controls.Add(textBoxArtist, 1, 1); + tableLayoutPanel1.Controls.Add(ButtonDelete, 2, 2); + tableLayoutPanel1.Controls.Add(comboBoxGenre, 1, 2); + tableLayoutPanel1.Controls.Add(ButtonUpdate, 2, 1); + tableLayoutPanel1.Controls.Add(ButtonAdd, 2, 0); + tableLayoutPanel1.Location = new Point(22, 78); + tableLayoutPanel1.Name = "tableLayoutPanel1"; + tableLayoutPanel1.RowCount = 4; + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 32F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 33F)); + tableLayoutPanel1.Size = new Size(289, 138); + tableLayoutPanel1.TabIndex = 19; + // + // textBoxSearch + // + textBoxSearch.Location = new Point(380, 45); + textBoxSearch.Name = "textBoxSearch"; + textBoxSearch.Size = new Size(125, 27); + textBoxSearch.TabIndex = 20; + // + // Form1 + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(800, 450); + Controls.Add(textBoxSearch); + Controls.Add(tableLayoutPanel1); + Controls.Add(ButtonDownDetik); + Controls.Add(ButtonUpDetik); + Controls.Add(textBoxDetik); + Controls.Add(label5); + Controls.Add(listBoxSongs); + Name = "Form1"; + Text = "Form1"; + Load += Form1_Load; + tableLayoutPanel1.ResumeLayout(false); + tableLayoutPanel1.PerformLayout(); + ResumeLayout(false); + PerformLayout(); } #endregion + + private TextBox textBoxTitle; + private TextBox textBoxArtist; + private ComboBox comboBoxGenre; + private CheckBox checkBoxIsAvailable; + private Button ButtonAdd; + private Button ButtonUpdate; + private Button ButtonDelete; + private ListBox listBoxSongs; + private Label label1; + private Label label2; + private Label label3; + private Label label5; + private TextBox textBoxDetik; + private Button ButtonUpDetik; + private Button ButtonDownDetik; + private TableLayoutPanel tableLayoutPanel1; + private TextBox textBoxSearch; } } diff --git a/ExamNETIntermediate/Form1.cs b/ExamNETIntermediate/Form1.cs index 3302c50..705affe 100644 --- a/ExamNETIntermediate/Form1.cs +++ b/ExamNETIntermediate/Form1.cs @@ -1,10 +1,266 @@ +using ExamNETIntermediate.Models; +using Newtonsoft.Json; +using System.Security.Cryptography.X509Certificates; +using System.Text; + namespace ExamNETIntermediate { public partial class Form1 : Form { + public const string ApiBaseUrl = "https://new-dev.accelist.com:10000"; + private bool isValid; + + public List Songs { get; set; } = new List(); + public List Genres { get; set; } = new List(); + public HttpClient HttpClient { get; set; } = new HttpClient(); + + public Form1() { InitializeComponent(); + PopulateGenreComboBox(); + //LoadGenresAndSongs(); + } + private async void Form1_Load(object sender, EventArgs e) + { + try + { + await LoadGenresAndSongs(); + if (Songs != null && Songs.Any()) + { + var uniqueGenres = Songs.Select(Song => Song.GenreName).Distinct(); + foreach (var genre in uniqueGenres) + { + comboBoxGenre.Items.Add(genre); + } + } + else + { + MessageBox.Show("No songs loaded. Please check your internet connection or try again later."); + } + } + catch (Exception ex) + { + MessageBox.Show($"An error onccurred : {ex.Message}"); + } + } + + private async Task LoadGenresAndSongs() + { + var genreResponse = await HttpClient.GetAsync($"{ApiBaseUrl}/api/genre"); + var songResponse = await HttpClient.GetAsync($"{ApiBaseUrl}/api/song"); + + if (genreResponse.IsSuccessStatusCode && songResponse.IsSuccessStatusCode) + { + var GenreJson = await genreResponse.Content.ReadAsStringAsync(); + var SongJson = await songResponse.Content.ReadAsStringAsync(); + + var Genres = JsonConvert.DeserializeObject>(GenreJson); + var Songs = JsonConvert.DeserializeObject>(SongJson); + + RefreshListBox(); + } + else + { + MessageBox.Show("Failed to fetch data from the API."); + } + } + private void PopulateGenreComboBox() + { + comboBoxGenre.Items.Clear(); + if (Genres != null && Genres.Any()) + { + foreach (var genre in Genres) + { + comboBoxGenre.Items.Add(new KeyValuePair(genre.genreId, genre.genreName)); + } + } + else + { + MessageBox.Show("No songs loaded. Please check your internet connection or try again later."); + } + + } + + private void RefreshListBox() + { + listBoxSongs.DataSource = null; + listBoxSongs.DisplayMember = "Title"; + listBoxSongs.DataSource = Songs.Select(Song => Song.Title).ToList(); + } + + private void listBoxSongs_SelectedIndexChanged(object sender, EventArgs e) + { + if (listBoxSongs.SelectedIndex != -1) + { + var selectedSong = Songs[listBoxSongs.SelectedIndex]; + textBoxTitle.Text = selectedSong.Title; + textBoxArtist.Text = selectedSong.Artist; + comboBoxGenre.SelectedItem = selectedSong.GenreName; + checkBoxIsAvailable.Checked = selectedSong.IsAvailable; + + } + else + { + ClearInputs(); + } + } + private void ClearInputs() + { + textBoxTitle.Clear(); + textBoxArtist.Clear(); + comboBoxGenre.SelectedItem = null; + checkBoxIsAvailable.Checked = false; + } + + private async void ButtonAdd_Click(object sender, EventArgs e) + { + + ValidateInputs(); + if (isValid) + { + var newSong = new Song + { + Title = textBoxTitle.Text, + Artist = textBoxArtist.Text, + GenreName = comboBoxGenre.Text, + IsAvailable = checkBoxIsAvailable.Checked, + }; + if (string.IsNullOrWhiteSpace(newSong.GenreName)) + { + MessageBox.Show("Please select a genre."); + return; + } + var json = JsonConvert.SerializeObject(newSong); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + + try + { + var response = await HttpClient.PostAsync($"{ApiBaseUrl}/api/song", content); + if (response.IsSuccessStatusCode) + { + MessageBox.Show("Song added successfully"); + await LoadGenresAndSongs(); + RefreshListBox(); + } + else + { + MessageBox.Show("Failed to add song."); + } + + } + catch (Exception ex) + { + MessageBox.Show($"An error occurred: {ex.Message}"); + } + + } + } + public void ValidateInputs() + { + if (string.IsNullOrWhiteSpace(textBoxTitle.Text)) + { + MessageBox.Show("Title cannot be empty."); + isValid = false; + } + + if (string.IsNullOrWhiteSpace(textBoxArtist.Text)) + { + MessageBox.Show("Artist cannot be empty."); + isValid = false; + } + + if (comboBoxGenre.SelectedItem == null) + { + MessageBox.Show("Please select a genre."); + isValid = false; + } + } + + private async void ButtonUpdate_Click(object sender, EventArgs e) + { + if (listBoxSongs.SelectedIndex!= -1) + { + var selectedSong = (Song)listBoxSongs.SelectedItem; + var updateSong = new Song + { + Title = textBoxTitle.Text, + Artist = textBoxArtist.Text, + GenreName = comboBoxGenre.Text, + IsAvailable = checkBoxIsAvailable.Checked + + }; + if (string.IsNullOrWhiteSpace(updateSong.GenreName)) + { + MessageBox.Show("Please select a genre"); + return; + } + var apiUrl = $"{ApiBaseUrl}/api/song/{selectedSong.SongId}"; + try + { + var json = JsonConvert.SerializeObject(updateSong); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + var response = await HttpClient.PutAsync(apiUrl, content); + if (response.IsSuccessStatusCode) + { + MessageBox.Show("Song to update successfully"); + RefreshListBox(); + } + else + { + MessageBox.Show("Failed to update song"); + return; + } + } + catch (Exception ex) + { + MessageBox.Show($"An error occurred while updating song {ex.Message}"); + } + } + } + + private async void ButtonDelete_Click(object sender, EventArgs e) + { + if (listBoxSongs.SelectedIndex != -1) + { + var selectedSong = (Song)listBoxSongs.SelectedItem; + var confirmation = MessageBox.Show("Are you sure you want to delete this song?", "Confirmation", MessageBoxButtons.YesNo); + if (confirmation == DialogResult.Yes) + { + var apiUrl = $"{ApiBaseUrl}/api/song/{selectedSong.SongId}"; + try + { + var response = await HttpClient.DeleteAsync(apiUrl); + if (response.IsSuccessStatusCode) + { + MessageBox.Show("Song deleted successfully"); + + await LoadGenresAndSongs(); + } + else + { + MessageBox.Show("Failed to delete song."); + } + } + catch (Exception ex) + { + MessageBox.Show($"An error occurred while delleting song : {ex.Message}"); + } + } + else + { + MessageBox.Show("Please select a song to delete."); + } + } + } + private void comboBoxGenre_SelectedIndexChanged(object sender, EventArgs e) + { + if (comboBoxGenre.SelectedItem != null) + { + string selectedGenre = ((KeyValuePair)comboBoxGenre.SelectedItem).Value; + comboBoxGenre.Text = selectedGenre; + } } } } + diff --git a/ExamNETIntermediate/Form1.resx b/ExamNETIntermediate/Form1.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/ExamNETIntermediate/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ExamNETIntermediate/Models/Song.cs b/ExamNETIntermediate/Models/Song.cs new file mode 100644 index 0000000..bdeaa51 --- /dev/null +++ b/ExamNETIntermediate/Models/Song.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExamNETIntermediate.Models +{ + public class Song + { + public int SongId { get; set; } + public string Title { get; set; } = string.Empty; + public string Artist { get; set; } = string.Empty; + public string GenreName { get; set; } = string.Empty; + public TimeSpan Lenght { get; set; } + public DateTime ReleaseDate { get; set; } + public bool IsAvailable { get; set; } + } + public class Genre + { + public int genreId { get; set; } + public string genreName { get; set; } = string.Empty; + + } + +}