from flask_wtf import FlaskForm from flask_wtf.file import FileAllowed, FileField from wtforms import BooleanField, DecimalField, EmailField, HiddenField, IntegerField, PasswordField, SelectField, StringField, SubmitField, TextAreaField from wtforms.fields import DateField from wtforms.validators import DataRequired, Email, EqualTo, Length, NumberRange, Optional class HoneypotMixin: website = StringField('Website', validators=[Optional()]) class LoginForm(HoneypotMixin, FlaskForm): email = EmailField('Email', validators=[DataRequired(), Email()]) password = PasswordField('Password', validators=[DataRequired()]) remember_me = BooleanField('Remember me') submit = SubmitField('Login') class RegistrationForm(HoneypotMixin, FlaskForm): full_name = StringField('Full name', validators=[DataRequired(), Length(max=120)]) email = EmailField('Email', validators=[DataRequired(), Email()]) password = PasswordField('Password', validators=[DataRequired(), Length(min=8)]) confirm_password = PasswordField('Confirm password', validators=[DataRequired(), EqualTo('password')]) submit = SubmitField('Create account') class ExpenseForm(FlaskForm): title = StringField('Title', validators=[Optional(), Length(max=255)]) amount = DecimalField('Amount', validators=[DataRequired(), NumberRange(min=0)], places=2) purchase_date = DateField('Purchase date', validators=[DataRequired()]) category_id = SelectField('Category', coerce=int, validators=[Optional()]) payment_method = SelectField('Payment method', choices=[('card', 'Card'), ('cash', 'Cash'), ('transfer', 'Transfer'), ('blik', 'BLIK')], validators=[DataRequired()]) document = FileField('Document', validators=[Optional(), FileAllowed(['jpg', 'jpeg', 'png', 'heic', 'pdf'])], render_kw={'multiple': True}) vendor = StringField('Vendor', validators=[Optional(), Length(max=255)]) description = TextAreaField('Description', validators=[Optional(), Length(max=2000)]) currency = SelectField('Currency', choices=[('PLN', 'PLN'), ('EUR', 'EUR'), ('USD', 'USD')], validators=[DataRequired()]) tags = StringField('Tags', validators=[Optional(), Length(max=255)]) recurring_period = SelectField('Recurring', choices=[('none', 'None'), ('monthly', 'Monthly'), ('yearly', 'Yearly')], validators=[DataRequired()]) status = SelectField('Status', choices=[('new', 'New'), ('needs_review', 'Needs review'), ('confirmed', 'Confirmed')], validators=[DataRequired()]) is_refund = BooleanField('Refund') is_business = BooleanField('Business') rotate = IntegerField('Rotate', validators=[Optional()], default=0) crop_x = HiddenField('Crop X', default='') crop_y = HiddenField('Crop Y', default='') crop_w = HiddenField('Crop W', default='') crop_h = HiddenField('Crop H', default='') scale_percent = IntegerField('Scale', validators=[Optional()], default=100) submit = SubmitField('Save expense') class CategoryForm(FlaskForm): key = StringField('Key', validators=[DataRequired(), Length(max=80)]) name_pl = StringField('Polish name', validators=[DataRequired(), Length(max=120)]) name_en = StringField('English name', validators=[DataRequired(), Length(max=120)]) color = SelectField('Color', choices=[('primary', 'Primary'), ('secondary', 'Secondary'), ('success', 'Success'), ('danger', 'Danger'), ('warning', 'Warning'), ('info', 'Info')], validators=[DataRequired()]) is_active = BooleanField('Active') submit = SubmitField('Save category') class UserAdminForm(FlaskForm): full_name = StringField('Full name', validators=[DataRequired(), Length(max=120)]) email = EmailField('Email', validators=[DataRequired(), Email()]) role = SelectField('Role', choices=[('user', 'User'), ('admin', 'Admin')], validators=[DataRequired()]) language = SelectField('Language', choices=[('pl', 'Polish'), ('en', 'English')], validators=[DataRequired()]) report_frequency = SelectField('Reports', choices=[('off', 'Off'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly')], default='off', validators=[Optional()]) theme = SelectField('Theme', choices=[('light', 'Light'), ('dark', 'Dark')], default='light', validators=[Optional()]) is_active_user = BooleanField('Active user', default=True) must_change_password = BooleanField('Must change password') submit = SubmitField('Save user') class ResetRequestForm(HoneypotMixin, FlaskForm): email = EmailField('Email', validators=[DataRequired(), Email()]) submit = SubmitField('Send reset link') class PasswordResetForm(FlaskForm): password = PasswordField('Password', validators=[DataRequired(), Length(min=8)]) confirm_password = PasswordField('Confirm password', validators=[DataRequired(), EqualTo('password')]) submit = SubmitField('Reset password') class PreferencesForm(FlaskForm): language = SelectField('Language', choices=[('pl', 'Polski'), ('en', 'English')], validators=[DataRequired()]) theme = SelectField('Theme', choices=[('light', 'Light'), ('dark', 'Dark')], validators=[DataRequired()]) report_frequency = SelectField('Reports', choices=[('off', 'Off'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly')], validators=[DataRequired()]) default_currency = SelectField('Currency', choices=[('PLN', 'PLN'), ('EUR', 'EUR'), ('USD', 'USD')], validators=[DataRequired()]) submit = SubmitField('Save preferences') class BudgetForm(FlaskForm): category_id = SelectField('Category', coerce=int, validators=[DataRequired()]) year = IntegerField('Year', validators=[DataRequired(), NumberRange(min=2000, max=2200)]) month = IntegerField('Month', validators=[DataRequired(), NumberRange(min=1, max=12)]) amount = DecimalField('Amount', validators=[DataRequired(), NumberRange(min=0)], places=2) alert_percent = IntegerField('Alert percent', validators=[DataRequired(), NumberRange(min=1, max=200)], default=80) submit = SubmitField('Save budget') class UserCategoryForm(FlaskForm): key = StringField('Key', validators=[DataRequired(), Length(max=80)]) name_pl = StringField('Polish name', validators=[DataRequired(), Length(max=120)]) name_en = StringField('English name', validators=[DataRequired(), Length(max=120)]) color = SelectField('Color', choices=[('primary', 'Primary'), ('secondary', 'Secondary'), ('success', 'Success'), ('danger', 'Danger'), ('warning', 'Warning'), ('info', 'Info')], validators=[DataRequired()]) submit = SubmitField('Save category')