from flask_wtf import FlaskForm from wtforms import StringField, TextAreaField, BooleanField, SubmitField, PasswordField, SelectMultipleField, SelectField from wtforms.validators import DataRequired, Email, Length, Optional, ValidationError from models import User from flask_login import current_user from flask_wtf.file import FileField, FileAllowed class UserForm(FlaskForm): first_name = StringField('First Name', validators=[DataRequired(), Length(min=2, max=100)]) last_name = StringField('Last Name', validators=[DataRequired(), Length(min=2, max=100)]) email = StringField('Email', validators=[DataRequired(), Email(), Length(max=150)]) phone = StringField('Phone (Optional)', validators=[Optional(), Length(max=20)]) company = StringField('Company (Optional)', validators=[Optional(), Length(max=100)]) position = StringField('Position (Optional)', validators=[Optional(), Length(max=100)]) notes = TextAreaField('Notes (Optional)', validators=[Optional()]) role = SelectField('Role', choices=[ ('user', 'Standard User'), ('manager', 'Manager'), ('admin', 'Administrator') ], validators=[DataRequired()]) new_password = PasswordField('New Password (Optional)') confirm_password = PasswordField('Confirm Password (Optional)') profile_picture = FileField('Profile Picture (Optional)', validators=[FileAllowed(['jpg', 'jpeg', 'png', 'gif'], 'Images only!')]) submit = SubmitField('Save Contact') def validate_is_admin(self, field): # Only validate when trying to uncheck admin status if not field.data: # Get the user being edited (either current user or a new user) user = User.query.filter_by(email=self.email.data).first() # If this is an existing admin user and they're the only admin if user and user.is_admin: total_admins = User.query.filter_by(is_admin=True).count() if total_admins <= 1: raise ValidationError('There must be at least one admin user in the system.') def validate_is_manager(self, field): # Prevent setting both admin and manager roles if field.data and self.is_admin.data: raise ValidationError('A user cannot be both an admin and a manager.') def validate(self, extra_validators=None): rv = super().validate(extra_validators=extra_validators) if not rv: return False if self.new_password.data or self.confirm_password.data: if not self.new_password.data or not self.confirm_password.data: self.confirm_password.errors.append('Both password fields are required.') return False if self.new_password.data != self.confirm_password.data: self.confirm_password.errors.append('Passwords must match.') return False return True class RoomForm(FlaskForm): name = StringField('Room Name', validators=[DataRequired(), Length(min=3, max=100)]) description = TextAreaField('Description', validators=[Optional(), Length(max=500)]) submit = SubmitField('Create Room') class ConversationForm(FlaskForm): name = StringField('Name', validators=[DataRequired(), Length(min=1, max=100)]) description = TextAreaField('Description') members = SelectMultipleField('Members', coerce=int) submit = SubmitField('Create Conversation') def __init__(self, *args, **kwargs): super(ConversationForm, self).__init__(*args, **kwargs) self.members.choices = [(u.id, f"{u.username} {u.last_name}") for u in User.query.filter_by(is_active=True).all()] class CompanySettingsForm(FlaskForm): company_name = StringField('Company Name', validators=[Optional(), Length(max=100)]) company_website = StringField('Website', validators=[Optional(), Length(max=200)]) company_email = StringField('Email', validators=[Optional(), Email(), Length(max=100)]) company_phone = StringField('Phone', validators=[Optional(), Length(max=20)]) company_address = StringField('Address', validators=[Optional(), Length(max=200)]) company_city = StringField('City', validators=[Optional(), Length(max=100)]) company_state = StringField('State', validators=[Optional(), Length(max=100)]) company_zip = StringField('ZIP Code', validators=[Optional(), Length(max=20)]) company_country = StringField('Country', validators=[Optional(), Length(max=100)]) company_description = TextAreaField('Description', validators=[Optional()]) company_industry = StringField('Industry', validators=[Optional(), Length(max=100)]) company_logo = FileField('Company Logo', validators=[FileAllowed(['jpg', 'jpeg', 'png', 'gif'], 'Images only!')])