diff --git a/app/models.py b/app/models.py
new file mode 100644
index 0000000..5d8e640
--- /dev/null
+++ b/app/models.py
@@ -0,0 +1,131 @@
+from flask.json import JSONEncoder
+from flask_admin import BaseView, expose
+from flask_babel import lazy_gettext as _
+
+from providers import User
+
+
+__author__ = 'hanl'
+
+from flask_wtf import Form
+from wtforms import PasswordField, StringField, validators, RadioField
+
+CHOICES = [('male', _('male')), ('female', _('female'))]
+
+
+class ReadonlyStringField(StringField):
+    def __call__(self, *args, **kwargs):
+        # kwargs.setdefault('readonly', True)
+        c = kwargs.pop('class', '') or kwargs.pop('class_', '')
+        kwargs['class'] = u'%s %s' % ('form-control-static', c)
+        return super(ReadonlyStringField, self).__call__(*args, **kwargs)
+
+
+class SigninForm(Form):
+    username = StringField(_("username"), [validators.DataRequired(_("enter.username"))])
+    password = PasswordField(_('password'), [validators.DataRequired(_("enter.password"))])
+    # submit = SubmitField("Sign in")
+
+    def __init__(self, *args, **kwargs):
+        Form.__init__(self, *args, **kwargs)
+
+    def validate(self):
+        if not Form.validate(self):
+            return False
+            # user = User.query.filter_by(email = self.email.data.lower()).first()
+            # if user and user.check_password(self.password.data):
+        return True
+        # else:
+        # self.email.errors.append("Invalid e-mail or password")
+        # return False
+
+
+class SignupForm(Form):
+    gender = RadioField(_("gender"), validators=[validators.DataRequired()], choices=CHOICES)
+    username = StringField(_("username"), [validators.DataRequired(_("enter.username"))])
+    password = PasswordField(_("password"), [validators.DataRequired(_("enter.password")),
+                                             validators.EqualTo("confirm", message=_("password.match"))])
+    confirm = PasswordField(_("confirm"))
+    firstName = StringField(_("firstName"), [validators.DataRequired(_("enter.firstName"))])
+    lastName = StringField(_("lastName"), [validators.DataRequired(_("enter.lastName"))])
+
+    email = StringField(_("email"), [validators.DataRequired(_("enter.email")),
+                                     validators.Email(_("enter.valid.email"))])
+
+
+    address = StringField(_("address"))
+    phone = StringField(_("phone"))
+    institution = StringField(_("institution"))
+    # recaptcha = RecaptchaField()
+
+    def __init__(self, *args, **kwargs):
+        Form.__init__(self, *args, **kwargs)
+
+    def validate(self):
+        if not Form.validate(self):
+            return False
+
+            # user = User.query.filter_by(email = self.email.data.lower()).first()
+            # if user:
+            # self.email.errors.append("That email is already taken")
+            # return False
+            # else:
+        return True
+
+
+class ProfileForm(Form):
+    username = ReadonlyStringField(_("username"))
+    email = StringField(_("email"), [validators.DataRequired(_("enter.email")),
+                                     validators.Email(_("enter.valid.email"))])
+    firstName = StringField(_("firstName"), [validators.DataRequired(_("enter.firstName"))])
+    lastName = StringField(_("lastName"), [validators.DataRequired(_("enter.lastName"))])
+
+    address = StringField(_("address"))
+    phone = StringField(_("phone"))
+    institution = StringField(_("institution"))
+
+    def __init__(self, *args, **kwargs):
+        Form.__init__(self, *args, **kwargs)
+
+    def validate(self):
+        if not Form.validate(self):
+            return False
+        return True
+
+
+class PasswordReset(Form):
+    pass
+
+
+class PasswordChangeForm(Form):
+    pass
+
+
+class UserEncoder(JSONEncoder):
+    def default(self, obj):
+        if isinstance(obj, User):
+            data = {}
+            if obj.firstName:
+                data['firstName'] = obj.firstName
+            if obj.lastName:
+                data['lastName'] = obj.lastName
+            if obj.email:
+                data['email'] = obj.email
+            if obj.country:
+                data['country'] = obj.country
+            if obj.institution:
+                data['institution'] = obj.institution
+            if obj.address:
+                data['address'] = obj.address
+            if obj.phone:
+                data['phone'] = obj.phone
+            return data
+        return super(UserEncoder, self).default(obj)
+
+
+
+
+class AdminView(BaseView):
+    @expose('/')
+    def index(self):
+        return self.render('admin/index.html')
\ No newline at end of file
