package com.andreiolar.abms.client.widgets;
import com.andreiolar.abms.client.exception.ComplaintSubmissionException;
import com.andreiolar.abms.client.exception.MailException;
import com.andreiolar.abms.client.rpc.DBSubmitComplaint;
import com.andreiolar.abms.client.rpc.DBSubmitComplaintAsync;
import com.andreiolar.abms.shared.UserDetails;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.FontWeight;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import gwt.material.design.addins.client.combobox.MaterialComboBox;
import gwt.material.design.addins.client.richeditor.MaterialRichEditor;
import gwt.material.design.client.constants.CollapsibleType;
import gwt.material.design.client.constants.Color;
import gwt.material.design.client.constants.IconPosition;
import gwt.material.design.client.constants.IconType;
import gwt.material.design.client.constants.InputType;
import gwt.material.design.client.constants.TextAlign;
import gwt.material.design.client.constants.WavesType;
import gwt.material.design.client.ui.MaterialButton;
import gwt.material.design.client.ui.MaterialCollapsible;
import gwt.material.design.client.ui.MaterialCollapsibleBody;
import gwt.material.design.client.ui.MaterialCollapsibleHeader;
import gwt.material.design.client.ui.MaterialCollapsibleItem;
import gwt.material.design.client.ui.MaterialLabel;
import gwt.material.design.client.ui.MaterialLink;
import gwt.material.design.client.ui.MaterialLoader;
import gwt.material.design.client.ui.MaterialModal;
import gwt.material.design.client.ui.MaterialPanel;
import gwt.material.design.client.ui.MaterialTextBox;
import gwt.material.design.client.ui.MaterialToast;
import gwt.material.design.client.ui.html.Div;
import gwt.material.design.client.ui.html.Hr;
import gwt.material.design.client.ui.html.OptGroup;
import gwt.material.design.client.ui.html.Option;
public class ComplaintsWidget extends Composite implements CustomWidget {
public UserDetails userDetails;
public ComplaintsWidget(UserDetails userDetails) {
this.userDetails = userDetails;
initWidget(initializeWidget());
}
@Override
public Widget initializeWidget() {
MaterialPanel panel = new MaterialPanel();
MaterialLabel title = new MaterialLabel("Complaints");
title.setTextColor(Color.BLUE);
title.setTextAlign(TextAlign.CENTER);
title.setFontSize("36px");
title.setFontWeight(FontWeight.BOLD);
panel.add(title);
panel.add(new Hr());
MaterialComboBox<String> institutionsBox = initInstitutions();
institutionsBox.setStyleName("comboboxInst");
institutionsBox.setTextAlign(TextAlign.CENTER);
panel.add(institutionsBox);
MaterialCollapsible collapsible = new MaterialCollapsible();
collapsible.setType(CollapsibleType.POPOUT);
collapsible.setGrid("s12 m6 l8");
collapsible.setVisibility(Visibility.HIDDEN);
collapsible.setMarginBottom(40.0);
MaterialCollapsibleItem collapsibleItem = new MaterialCollapsibleItem();
MaterialCollapsibleHeader collapsibleHeader = new MaterialCollapsibleHeader();
MaterialLink collapsibleLink = new MaterialLink();
collapsibleLink.setText("Important Note!");
collapsibleLink.setIconType(IconType.INFO_OUTLINE);
collapsibleLink.setIconPosition(IconPosition.LEFT);
collapsibleLink.setTextColor(Color.BLUE);
collapsibleHeader.add(collapsibleLink);
MaterialCollapsibleBody collapsibleBody = new MaterialCollapsibleBody();
MaterialLabel collapsibleLabel = new MaterialLabel();
collapsibleLabel.getElement().setInnerHTML(
"<b>Important Note!</b><br />You are about to write a complaint. Please think carefully about this. Fake complaints will be punished by law!<br />To submit a complaint to the "
+ institutionsBox.getSelectedValue()
+ " please use the form below.<br />Only phone number is editable. If other fields do not match, please edit them in your account settings before writing the actual complaint.");
collapsibleBody.add(collapsibleLabel);
institutionsBox.addValueChangeHandler(new ValueChangeHandler<String>() {
@Override
public void onValueChange(ValueChangeEvent<String> event) {
String selected = event.getValue();
if (!selected.equals("Select Institution")) {
collapsibleLabel.getElement().setInnerHTML(
"<b>Important Note!</b><br />You are about to write a complaint. Please think carefully about this. Fake complaints will be punished by law!<br />To submit a complaint to the "
+ institutionsBox.getSelectedValue()
+ " please use the form below.<br />Only phone number is editable. If other fields do not match, please edit them in your account settings before writing the actual complaint.");
collapsible.setVisibility(Visibility.VISIBLE);
} else {
collapsible.setVisibility(Visibility.HIDDEN);
}
}
});
collapsibleItem.add(collapsibleHeader);
collapsibleItem.add(collapsibleBody);
collapsible.add(collapsibleItem);
panel.add(collapsible);
// Other inputs
MaterialTextBox firstNameBox = new MaterialTextBox();
firstNameBox.setType(InputType.TEXT);
firstNameBox.setPlaceholder("First Name");
firstNameBox.setMaxLength(30);
firstNameBox.setLength(30);
firstNameBox.setIconType(IconType.PERSON);
firstNameBox.setText(userDetails.getFirstName());
firstNameBox.setEnabled(false);
firstNameBox.setStyleName("complaintsComponent");
panel.add(firstNameBox);
MaterialTextBox lastNameBox = new MaterialTextBox();
lastNameBox.setType(InputType.TEXT);
lastNameBox.setPlaceholder("Last Name");
lastNameBox.setMaxLength(30);
lastNameBox.setLength(30);
lastNameBox.setIconType(IconType.PERSON);
lastNameBox.setText(userDetails.getLastName());
lastNameBox.setEnabled(false);
lastNameBox.setStyleName("complaintsComponent");
panel.add(lastNameBox);
MaterialTextBox mobileNumberBox = new MaterialTextBox();
mobileNumberBox.setType(InputType.TEL);
mobileNumberBox.setPlaceholder("Phone Number");
mobileNumberBox.setMaxLength(10);
mobileNumberBox.setLength(10);
mobileNumberBox.setIconType(IconType.SMARTPHONE);
mobileNumberBox.setText(userDetails.getMobileNumber());
mobileNumberBox.setStyleName("complaintsComponent");
panel.add(mobileNumberBox);
MaterialTextBox cnpBox = new MaterialTextBox();
cnpBox.setType(InputType.TEXT);
cnpBox.setPlaceholder("CNP");
cnpBox.setMaxLength(13);
cnpBox.setLength(13);
cnpBox.setIconType(IconType.PERM_IDENTITY);
cnpBox.setText(userDetails.getPersonalNumber());
cnpBox.setEnabled(false);
cnpBox.setStyleName("complaintsComponent");
panel.add(cnpBox);
MaterialTextBox personalNumberBox = new MaterialTextBox();
personalNumberBox.setType(InputType.TEXT);
personalNumberBox.setPlaceholder("ID Series and Number");
personalNumberBox.setMaxLength(8);
personalNumberBox.setLength(8);
personalNumberBox.setIconType(IconType.PERM_IDENTITY);
personalNumberBox.setText(userDetails.getIdSeries());
personalNumberBox.setEnabled(false);
personalNumberBox.setStyleName("complaintsComponent");
panel.add(personalNumberBox);
Div div = new Div();
div.setHeight("360px");
div.setStyleName("complaintsEditor");
MaterialRichEditor editor = new MaterialRichEditor();
editor.setPlaceholder("Your complaint here.");
editor.setHeight("150px");
div.add(editor);
panel.add(div);
Div buttonsDiv = new Div();
buttonsDiv.setStyleName("twoButtons");
MaterialButton submitButton = new MaterialButton();
submitButton.setWaves(WavesType.LIGHT);
submitButton.setText("Submit");
submitButton.setWidth("15%");
submitButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
String mobileNumber = mobileNumberBox.getText();
String complaintTo = institutionsBox.getSelectedValue();
String complaintText = editor.getHTML();
boolean canProcceed = true;
if (complaintTo.equals("Select Institution")) {
canProcceed = false;
institutionsBox.setError("Please select an institution.");
} else {
institutionsBox.setSuccess("");
}
if (!mobileNumber.matches("[0-9]{10}")) {
canProcceed = false;
mobileNumberBox.setError("Please enter a valid phone number. Only digits are allowed.");
} else {
mobileNumberBox.setSuccess("");
}
if (canProcceed) {
MaterialLoader.showLoading(true);
DBSubmitComplaintAsync rpcService = (DBSubmitComplaintAsync) GWT.create(DBSubmitComplaint.class);
ServiceDefTarget target = (ServiceDefTarget) rpcService;
String moduleRelativeURL = GWT.getModuleBaseURL() + "DBSubmitComplaintImpl";
target.setServiceEntryPoint(moduleRelativeURL);
rpcService.registerComplaint(userDetails, mobileNumber, complaintTo, complaintText, new AsyncCallback<Boolean>() {
@Override
public void onSuccess(Boolean result) {
MaterialLoader.showLoading(false);
MaterialToast.fireToast("Complaint submitted successfully!", "rounded");
}
@Override
public void onFailure(Throwable caught) {
MaterialLoader.showLoading(false);
if (caught instanceof ComplaintSubmissionException || caught instanceof MailException) {
MaterialToast.fireToast(caught.getMessage(), "rounded");
} else {
MaterialModal errorModal = ModalCreator.createModal(caught);
RootPanel.get().add(errorModal);
errorModal.open();
}
}
});
institutionsBox.setSelectedIndex(0);
mobileNumberBox.setText(userDetails.getMobileNumber());
editor.setHTML("");
}
}
});
buttonsDiv.add(submitButton);
MaterialButton clearButton = new MaterialButton();
clearButton.setWaves(WavesType.LIGHT);
clearButton.setText("Clear");
clearButton.setWidth("15%");
clearButton.setMarginLeft(25.0);
clearButton.setBackgroundColor(Color.LIGHT_BLUE_LIGHTEN_3);
clearButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
mobileNumberBox.setText(userDetails.getMobileNumber());
editor.setHTML("");
}
});
buttonsDiv.add(clearButton);
panel.add(buttonsDiv);
return panel;
}
private MaterialComboBox<String> initInstitutions() {
MaterialComboBox<String> institutionsBox = new MaterialComboBox<>();
institutionsBox.setPlaceholder("Institution");
institutionsBox.add(new Option("Select Institution"));
OptGroup emergencyServicesGroup = new OptGroup();
emergencyServicesGroup.setLabel("Emergency Services");
emergencyServicesGroup.add(new Option("Local Police"));
emergencyServicesGroup.add(new Option("National Police"));
emergencyServicesGroup.add(new Option("Medical Service"));
emergencyServicesGroup.add(new Option("Firefighter Service"));
institutionsBox.add(emergencyServicesGroup);
OptGroup publicTransportGroup = new OptGroup();
publicTransportGroup.setLabel("Transportation");
publicTransportGroup.add(new Option("Public Transportation"));
publicTransportGroup.add(new Option("National Railway Company"));
publicTransportGroup.add(new Option("Airport"));
institutionsBox.add(publicTransportGroup);
OptGroup otherGroup = new OptGroup();
otherGroup.setLabel("Other");
otherGroup.add(new Option("Salubrity"));
otherGroup.add(new Option("Town Hall"));
institutionsBox.add(otherGroup);
institutionsBox.setSelectedIndex(0);
return institutionsBox;
}
}