diff --git a/ExamNETIntermediate/Exam WinForms.docx b/ExamNETIntermediate/Exam WinForms.docx index a16ef9b..0dd3d7f 100644 Binary files a/ExamNETIntermediate/Exam WinForms.docx and b/ExamNETIntermediate/Exam WinForms.docx differ diff --git a/ExamNETIntermediate/Form1.Designer.cs b/ExamNETIntermediate/Form1.Designer.cs index ece918a..20e0b6e 100644 --- a/ExamNETIntermediate/Form1.Designer.cs +++ b/ExamNETIntermediate/Form1.Designer.cs @@ -28,12 +28,238 @@ 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"; + listBoxLagu = new ListBox(); + buttonRefresh = new Button(); + buttonAddInit = new Button(); + tableLayoutPanel1 = new TableLayoutPanel(); + textBoxTitle = new TextBox(); + textBoxArtist = new TextBox(); + comboBoxGenre = new ComboBox(); + checkBoxIsAvailable = new CheckBox(); + numericUpDownSecond = new NumericUpDown(); + numericUpDownMinute = new NumericUpDown(); + buttonAdd = new Button(); + buttonUpdate = new Button(); + buttonDelete = new Button(); + dateTimePickerRelease = new DateTimePicker(); + textBoxMessage = new TextBox(); + label1 = new Label(); + textBoxSearch = new TextBox(); + tableLayoutPanel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)numericUpDownSecond).BeginInit(); + ((System.ComponentModel.ISupportInitialize)numericUpDownMinute).BeginInit(); + SuspendLayout(); + // + // listBoxLagu + // + listBoxLagu.FormattingEnabled = true; + listBoxLagu.Location = new Point(32, 12); + listBoxLagu.Name = "listBoxLagu"; + listBoxLagu.Size = new Size(490, 164); + listBoxLagu.TabIndex = 0; + listBoxLagu.SelectedIndexChanged += ListBoxLagu_SelectedIndexChanged; + // + // buttonRefresh + // + buttonRefresh.Location = new Point(528, 41); + buttonRefresh.Name = "buttonRefresh"; + buttonRefresh.Size = new Size(94, 29); + buttonRefresh.TabIndex = 1; + buttonRefresh.Text = "Refresh"; + buttonRefresh.UseVisualStyleBackColor = true; + buttonRefresh.Click += ButtonRefresh_Click; + // + // buttonAddInit + // + buttonAddInit.Location = new Point(528, 76); + buttonAddInit.Name = "buttonAddInit"; + buttonAddInit.Size = new Size(94, 29); + buttonAddInit.TabIndex = 3; + buttonAddInit.Text = "Add Song"; + buttonAddInit.UseVisualStyleBackColor = true; + buttonAddInit.Click += ButtonAddInit_Click; + // + // tableLayoutPanel1 + // + tableLayoutPanel1.AutoSize = true; + tableLayoutPanel1.ColumnCount = 2; + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 39.11007F)); + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 60.88993F)); + tableLayoutPanel1.Controls.Add(textBoxTitle, 0, 0); + tableLayoutPanel1.Controls.Add(textBoxArtist, 1, 0); + tableLayoutPanel1.Controls.Add(comboBoxGenre, 0, 1); + tableLayoutPanel1.Controls.Add(checkBoxIsAvailable, 1, 1); + tableLayoutPanel1.Controls.Add(numericUpDownSecond, 1, 2); + tableLayoutPanel1.Controls.Add(numericUpDownMinute, 0, 2); + tableLayoutPanel1.Controls.Add(buttonAdd, 0, 3); + tableLayoutPanel1.Controls.Add(buttonUpdate, 0, 4); + tableLayoutPanel1.Controls.Add(buttonDelete, 1, 4); + tableLayoutPanel1.Controls.Add(dateTimePickerRelease, 1, 3); + tableLayoutPanel1.Location = new Point(221, 185); + tableLayoutPanel1.Name = "tableLayoutPanel1"; + tableLayoutPanel1.RowCount = 5; + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 42F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 41F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 43F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 59F)); + tableLayoutPanel1.Size = new Size(420, 253); + tableLayoutPanel1.TabIndex = 4; + // + // textBoxTitle + // + textBoxTitle.Location = new Point(3, 3); + textBoxTitle.Name = "textBoxTitle"; + textBoxTitle.PlaceholderText = "Enter Song Title"; + textBoxTitle.Size = new Size(125, 27); + textBoxTitle.TabIndex = 0; + // + // textBoxArtist + // + textBoxArtist.Location = new Point(167, 3); + textBoxArtist.Name = "textBoxArtist"; + textBoxArtist.PlaceholderText = "Enter Artist Name"; + textBoxArtist.Size = new Size(125, 27); + textBoxArtist.TabIndex = 1; + // + // comboBoxGenre + // + comboBoxGenre.FormattingEnabled = true; + comboBoxGenre.Location = new Point(3, 66); + comboBoxGenre.Name = "comboBoxGenre"; + comboBoxGenre.Size = new Size(150, 28); + comboBoxGenre.TabIndex = 2; + comboBoxGenre.Text = "Select Genre"; + // + // checkBoxIsAvailable + // + checkBoxIsAvailable.AutoSize = true; + checkBoxIsAvailable.Location = new Point(167, 66); + checkBoxIsAvailable.Name = "checkBoxIsAvailable"; + checkBoxIsAvailable.Size = new Size(93, 24); + checkBoxIsAvailable.TabIndex = 3; + checkBoxIsAvailable.Text = "Available"; + checkBoxIsAvailable.UseVisualStyleBackColor = true; + // + // numericUpDownSecond + // + numericUpDownSecond.Location = new Point(167, 129); + numericUpDownSecond.Name = "numericUpDownSecond"; + numericUpDownSecond.Size = new Size(150, 27); + numericUpDownSecond.TabIndex = 5; + // + // numericUpDownMinute + // + numericUpDownMinute.Location = new Point(3, 129); + numericUpDownMinute.Maximum = new decimal(new int[] { 59, 0, 0, 0 }); + numericUpDownMinute.Name = "numericUpDownMinute"; + numericUpDownMinute.Size = new Size(150, 27); + numericUpDownMinute.TabIndex = 4; + // + // buttonAdd + // + buttonAdd.Location = new Point(3, 171); + buttonAdd.Name = "buttonAdd"; + buttonAdd.Size = new Size(94, 29); + buttonAdd.TabIndex = 8; + buttonAdd.Text = "Add"; + buttonAdd.UseVisualStyleBackColor = true; + buttonAdd.Click += ButtonAdd_Click; + // + // buttonUpdate + // + buttonUpdate.Location = new Point(3, 212); + buttonUpdate.Name = "buttonUpdate"; + buttonUpdate.Size = new Size(94, 29); + buttonUpdate.TabIndex = 10; + buttonUpdate.Text = "Update"; + buttonUpdate.UseVisualStyleBackColor = true; + buttonUpdate.Click += ButtonUpdate_Click; + // + // buttonDelete + // + buttonDelete.Location = new Point(167, 212); + buttonDelete.Name = "buttonDelete"; + buttonDelete.Size = new Size(94, 29); + buttonDelete.TabIndex = 9; + buttonDelete.Text = "Delete"; + buttonDelete.UseVisualStyleBackColor = true; + buttonDelete.Click += ButtonDelete_Click; + // + // dateTimePickerRelease + // + dateTimePickerRelease.Location = new Point(167, 171); + dateTimePickerRelease.Name = "dateTimePickerRelease"; + dateTimePickerRelease.Size = new Size(250, 27); + dateTimePickerRelease.TabIndex = 11; + // + // textBoxMessage + // + textBoxMessage.Location = new Point(42, 314); + textBoxMessage.Name = "textBoxMessage"; + textBoxMessage.Size = new Size(161, 27); + textBoxMessage.TabIndex = 11; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new Point(32, 258); + label1.Name = "label1"; + label1.Size = new Size(186, 20); + label1.TabIndex = 5; + label1.Text = "Duration (Minute, Second):"; + // + // textBoxSearch + // + textBoxSearch.Location = new Point(530, 128); + textBoxSearch.Name = "textBoxSearch"; + textBoxSearch.PlaceholderText = "Enter song title or artist to search"; + textBoxSearch.Size = new Size(258, 27); + textBoxSearch.TabIndex = 6; + textBoxSearch.TextAlign = HorizontalAlignment.Center; + textBoxSearch.TextChanged += TextBoxSearch_TextChanged; + // + // Form1 + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(800, 450); + Controls.Add(textBoxSearch); + Controls.Add(label1); + Controls.Add(tableLayoutPanel1); + Controls.Add(buttonAddInit); + Controls.Add(buttonRefresh); + Controls.Add(listBoxLagu); + Controls.Add(textBoxMessage); + Name = "Form1"; + Text = "Form1"; + tableLayoutPanel1.ResumeLayout(false); + tableLayoutPanel1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)numericUpDownSecond).EndInit(); + ((System.ComponentModel.ISupportInitialize)numericUpDownMinute).EndInit(); + ResumeLayout(false); + PerformLayout(); } #endregion + + private ListBox listBoxLagu; + private Button buttonRefresh; + private Button buttonAddInit; + private TableLayoutPanel tableLayoutPanel1; + private TextBox textBoxTitle; + private TextBox textBoxArtist; + private ComboBox comboBoxGenre; + private CheckBox checkBoxIsAvailable; + private NumericUpDown numericUpDownMinute; + private NumericUpDown numericUpDownSecond; + private Button buttonAdd; + private Button buttonDelete; + private Button buttonUpdate; + private Label label1; + private TextBox textBoxSearch; + private TextBox textBoxMessage; + private DateTimePicker dateTimePickerRelease; } } diff --git a/ExamNETIntermediate/Form1.cs b/ExamNETIntermediate/Form1.cs index 3302c50..de7a4df 100644 --- a/ExamNETIntermediate/Form1.cs +++ b/ExamNETIntermediate/Form1.cs @@ -1,10 +1,263 @@ +using ExamNETIntermediate.Models; +using Newtonsoft.Json; +using System.Text; +using System.Text.Json; + namespace ExamNETIntermediate { public partial class Form1 : Form { + public List SongModels { get; set; } = new List(); + public List Genres { get; set; } = new List(); + public HttpClient _httpClient { get; set; } = new HttpClient(); public Form1() { InitializeComponent(); + PopulateListBox(); + PopulateComboBox(); + } + + // Simple Methods to set length in minute and second + public int LengthConvertMinute(int length) + { + int minute = length / 60; + return minute; + } + + public int LengthConvertSecond(int length) + { + int second = length & 60; + return second; + } + + // Method to convert input music length to actual length in seconds + public int LengthInSecond(int minute, int second) + { + return (minute * 60) + second; + } + + // Method to generate List Box value + public async Task PopulateListBox() + { + var response = await _httpClient.GetAsync("https://new-dev.accelist.com:10000/api/song"); + response.EnsureSuccessStatusCode(); + var jsonContent = await response.Content.ReadAsStringAsync(); + + var content = JsonConvert.DeserializeObject>(jsonContent); + if (content != null) /// Jika Objek sudah di deserialisasi, dan object tidak null, maka SongModels akan diisi oleh object + { + SongModels = content; + } + + listBoxLagu.Items.Clear(); + listBoxLagu.Items.AddRange(SongModels.ToArray()); + + listBoxLagu.DisplayMember = "Title"; + } + + // Method to generate combo box value + public async void PopulateComboBox() + { + var response = await _httpClient.GetAsync("https://new-dev.accelist.com:10000/api/genre"); + response.EnsureSuccessStatusCode(); + + var jsonContent = await response.Content.ReadAsStringAsync(); + var genres = JsonConvert.DeserializeObject>(jsonContent); + + if (genres != null) + { + Genres = genres; + } + comboBoxGenre.Items.Clear(); + comboBoxGenre.Items.AddRange(Genres.ToArray()); + comboBoxGenre.DisplayMember = "GenreName"; + } + + // Method to select the current index option and then auto fill the properties in tableLayout + private void ListBoxLagu_SelectedIndexChanged(object sender, EventArgs e) + { + var selectedItem = listBoxLagu.SelectedItem as SongModel; + if (selectedItem == null) return; + textBoxTitle.Text = selectedItem.Title; + textBoxArtist.Text = selectedItem.Artist; + checkBoxIsAvailable.Checked = selectedItem.IsAvailable; + int length = selectedItem.Length; + int minute = LengthConvertMinute(length); + int second = LengthConvertSecond(length); + numericUpDownMinute.Value = minute; + numericUpDownSecond.Value = second; + + var currentGenre = Genres.Where(R => R.GenreName == selectedItem.GenreName).FirstOrDefault(); + + comboBoxGenre.SelectedItem = currentGenre; + } + + /// Method to add new song data into the list + private async void ButtonAdd_Click(object sender, EventArgs e) + { + var songName = textBoxTitle.Text; + var songArtist = textBoxArtist.Text; + var selectedGenre = comboBoxGenre.SelectedItem as GenreModel; + int selectedMinute = (int)numericUpDownMinute.Value; + int selectedSecond = (int)numericUpDownSecond.Value; + var asSecond = LengthInSecond(selectedMinute, selectedSecond); + + + // Validation logic + if (string.IsNullOrEmpty(songName) || string.IsNullOrEmpty(songArtist)) + { + textBoxMessage.Text = "Song or artist name can't be empty!"; + return; + } + else if (selectedGenre == null) + { + textBoxMessage.Text = "Genre can't be empty"; + return; + } + else if (selectedMinute <= 0 || selectedMinute >= 59) + { + textBoxMessage.Text = "Minute must be between 1 and 59"; + return; + } + else if (selectedSecond <= 0 && selectedMinute == 0 || selectedSecond >= 59) + { + textBoxMessage.Text = "Second must be between 0 and 59"; + return; + } + + var songModel = new SongModelInput() + { + Title = songName, + Artist = songArtist, + GenreId = selectedGenre.GenreId, + IsAvailable = checkBoxIsAvailable.Checked, + Length = asSecond, + ReleaseDate = DateTime.UtcNow + }; + + var jsonString = JsonConvert.SerializeObject(songModel); + + var content = new StringContent(jsonString); + content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); + + var response = await _httpClient.PostAsync("https://new-dev.accelist.com:10000/api/song", content); + response.EnsureSuccessStatusCode(); + if (response.IsSuccessStatusCode) + { + textBoxMessage.Text = "Added new Song"; + } + else + { + textBoxMessage.Text = "Failed to add new Song"; + } + await PopulateListBox(); + } + + private async void ButtonRefresh_Click(object sender, EventArgs e) + { + await PopulateListBox(); + } + + private async void ButtonDelete_Click(object sender, EventArgs e) + { + var selectedSongIndex = listBoxLagu.SelectedIndex; + var selectedSong = listBoxLagu.Items[selectedSongIndex] as SongModel; + + if (selectedSong == null) + { + textBoxMessage.Text = "Can't delete"; + return; + } + var response = await _httpClient.DeleteAsync($"https://new-dev.accelist.com:10000/api/song/{selectedSong.SongId}"); + + if (response.IsSuccessStatusCode) + { + textBoxMessage.Text = "Success"; + } + else + { + textBoxMessage.Text = "failed"; + } + + await PopulateListBox(); + } + + private async void ButtonUpdate_Click(object sender, EventArgs e) + { + if (listBoxLagu.SelectedItem != null) + { + var selectedSong = listBoxLagu.SelectedItem as SongModel; + var songName = textBoxTitle.Text; + var songArtist = textBoxArtist.Text; + var selectedGenre = comboBoxGenre.SelectedItem as GenreModel; + int selectedMinute = (int)numericUpDownMinute.Value; + int selectedSecond = (int)numericUpDownSecond.Value; + var asSecond = LengthInSecond(selectedMinute, selectedSecond); + + if (string.IsNullOrEmpty(songName)) + { + textBoxMessage.Text = "Song Name can't be empty"; + return; + } + + if (string.IsNullOrEmpty(songArtist)) + { + textBoxMessage.Text = "Song Artist can't be empty"; + return; + } + + var updateModel = new SongModelInput + { + SongId = selectedSong.SongId, + Title = songName, + IsAvailable = checkBoxIsAvailable.Checked, + Artist = songArtist, + Length = asSecond, + ReleaseDate = DateTime.UtcNow, + GenreId = selectedGenre.GenreId + }; + var jsonString = JsonConvert.SerializeObject(updateModel); + var content = new StringContent(jsonString); + content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); + + var response = await _httpClient.PutAsync("https://new-dev.accelist.com:10000/api/song", content); + response.EnsureSuccessStatusCode(); + if (response.IsSuccessStatusCode) + { + textBoxMessage.Text = "Song updated"; + } + else + { + textBoxMessage.Text = "Failed to update Song"; + } + + } + await PopulateListBox(); + } + + private void ButtonAddInit_Click(object sender, EventArgs e) + { + ClearForm(); + } + + public void ClearForm() + { + listBoxLagu.SelectedItem = null; + textBoxTitle.Text = string.Empty; + textBoxArtist.Text = string.Empty; + comboBoxGenre.SelectedItem = null; + checkBoxIsAvailable.Checked = false; + numericUpDownMinute.Value = 0; + numericUpDownSecond.Value = 0; + dateTimePickerRelease.Value = DateTime.UtcNow; + } + + private void TextBoxSearch_TextChanged(object sender, EventArgs e) + { + var textToSearch = textBoxSearch.Text.ToLower(); + var filteredText = SongModels.Where(M => M.Title.ToLower().Contains(textToSearch)).ToList(); + listBoxLagu.Items.Clear(); + listBoxLagu.Items.AddRange(filteredText.ToArray()); } } } 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/GenreModel.cs b/ExamNETIntermediate/Models/GenreModel.cs new file mode 100644 index 0000000..11f2b96 --- /dev/null +++ b/ExamNETIntermediate/Models/GenreModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExamNETIntermediate.Models +{ + public class GenreModel + { + public int GenreId { get; set; } + public string GenreName { get; set; } = string.Empty; + } +} diff --git a/ExamNETIntermediate/Models/SongModel.cs b/ExamNETIntermediate/Models/SongModel.cs new file mode 100644 index 0000000..93caff9 --- /dev/null +++ b/ExamNETIntermediate/Models/SongModel.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExamNETIntermediate.Models +{ + public class SongModel + { + 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 int Length { get; set; } + public string ReleaseDate { get; set; } = string.Empty; + public bool IsAvailable { get; set; } + } + + public class SongModelInput + { + public int SongId { get; set; } + public string Title { get; set; } = string.Empty; + public string Artist { get; set; } = string.Empty; + public int GenreId { get; set; } + public bool IsAvailable { get; set; } + public int Length { get; set; } + public DateTime ReleaseDate { get; set; } + } +}