first commit

This commit is contained in:
Mateusz Gruszczyński
2026-03-13 15:17:32 +01:00
commit 986ffb200a
91 changed files with 4423 additions and 0 deletions

107
app/forms.py Normal file
View File

@@ -0,0 +1,107 @@
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')