diff --git a/asset/css/main.css b/asset/css/main.css
index e1723e0..8564282 100644
--- a/asset/css/main.css
+++ b/asset/css/main.css
@@ -143,3 +143,26 @@ strong,table thead th {
#footer p {
margin:0px;
}
+/* Ensure the form is displayed inline */
+form {
+ display: inline;
+}
+
+/* Delete Button Styles */
+.delete-button {
+ color: red;
+ background-color: transparent;
+ border: none;
+ cursor: pointer;
+ font-size: 18px;
+ padding: 0;
+}
+
+.delete-button i {
+ color: red;
+ font-size: 18px;
+}
+
+.delete-customer .icon {
+ color: red;
+}
diff --git a/asset/js/main.js b/asset/js/main.js
old mode 100644
new mode 100755
index d6cddf2..3212414
--- a/asset/js/main.js
+++ b/asset/js/main.js
@@ -10,7 +10,7 @@ var app = app || {};
// Initialize JQuery.
(function($) {
-
+
// Pager controller.
app.pager = function(params) {
this.name = params['name'];
@@ -166,6 +166,7 @@ var app = app || {};
crossDomain:false
}).done(function(data,status,request) {
output = data;
+ console.log('Fetched contacts:', output); // Log the fetched contacts
});
if(output!==null) {
switch(output['status']) {
@@ -211,6 +212,7 @@ var app = app || {};
thead.append(thead_row);
$.each(this.items,function(index,item) {
var tbody_row = `
+
`+item['name']+`
@@ -223,12 +225,48 @@ var app = app || {};
+
+
+
+ |
+
+ `;
+ tbody.append(tbody_row);
+ });
+ break;
+
+ case 'contact':
+ var thead_row = `
+
+ FirstName |
+ LastName |
+ Email |
+ Phonenumber |
+ Actions |
+
+ `;
+ thead.append(thead_row);
+ console.log(this.items); // Log the fetched contact data
+ $.each(this.items,function(index,item) {
+ var tbody_row = `
+
+
+ `+item['firstname']+ ' ' +item['lastname']+`
+ `+item['description']+`
+ |
+ `+item['email']+` |
+ `+item['phonenumber']+` |
+
+
+
+
|
`;
tbody.append(tbody_row);
});
break;
+
default:
break;
}
diff --git a/controller/contact.py b/controller/contact.py
index 4d19871..1f2e3b8 100644
--- a/controller/contact.py
+++ b/controller/contact.py
@@ -6,15 +6,113 @@
##
# Import community modules.
-from flask import render_template
+import math
+import logging
+from decimal import Decimal
+from flask import render_template, jsonify, redirect, request
# Import custom modules.
from controller import root_web_controller
-
+from model.customer import customer
+from model.contact import contact
# Contact web controller.
class contact_web_controller(root_web_controller):
# HTTP GET method processor.
def get(self,*args,**kwargs):
- return render_template('main.html',var=self.var)
+ if self.request.path == '/contacts':
+ if self.request.args.get('count'):
+ contacts = contact().count()
+ if contacts>0:
+ limit = Decimal(5.0)
+ pages = math.ceil(contacts/limit)
+ return jsonify({'status': 'success', 'result': {'count': contacts, 'pages': int(pages)}})
+ else:
+ return jsonify({'status': 'failure', 'message': 'Not available.'})
+ else:
+ limit = 5
+ offset = (int(self.request.args.get('page'))*limit)-limit if self.request.args.get('page') else 0
+ contacts = contact().list(offset=offset,limit=limit)
+ return jsonify({'status':'success','result': {'items': contacts}})
+ elif self.request.path=='/customer/'+args[0]+'/dashboard':
+ customer_id = args[0]
+ self.var['customer'] = customer().get(customer_id)
+ self.var['contacts'] = contact().list_for_customer(customer_id)
+ print("Fetched contacts for customer {}: {}".format(customer_id, self.var['contacts'])) # Debugging line
+ return render_template('customer/dashboard.html', var=self.var)
+ elif self.request.path=='/customer/'+args[0]+'/contact/create':
+ customer_id = args[0]
+ self.var['customer'] = customer().get(customer_id)
+ self.var['contacts'] = contact().list_for_customer(customer_id)
+ print self.var['customer']
+ return render_template('contact/create.html',var=self.var)
+ elif len(args) < 2:
+ self.var['error_message'] = "Missing customer or contact ID."
+ return render_template('error.html', var=self.var)
+ elif self.request.path=='/customer/'+args[0]+'/contact/'+args[1]+'/update':
+ contact_id = args[1]
+ customer_id = args[0]
+ if 'contact' in self.var:
+ print(self.var['contact'])
+ else:
+ print("Contact data not found!")
+ self.var['contact'] = contact().get(customer_id, contact_id)
+ self.var['customer'] = customer().get(customer_id)
+ return render_template('contact/update.html', var=self.var)
+ elif len(args) < 2:
+ self.var['error_message'] = "Missing customer or contact ID."
+ return render_template('error.html', var=self.var)
+ elif self.request.path == '/customer/'+args[0] +'/contact/'+args[1]+'/delete':
+ customer_id = args[0]
+ contact_id = args[1]
+ if contact().delete(contact_id):
+ return redirect('/customer/'+args[0]+'/dashboard')
+ else:
+ self.var['error_message'] = "There was an issue deleting the contact."
+ return render_template('error.html', var=self.var)
+
+ # HTTP POST method processor.
+ def post(self, *args, **kwargs):
+ if self.request.path=='/customer/'+args[0]+'/contact/create':
+ data = {
+ 'firstname': self.request.form.get('firstname'),
+ 'lastname': self.request.form.get('lastname'),
+ 'email': self.request.form.get('email'),
+ 'phonenumber': self.request.form.get('phonenumber'),
+ 'description': self.request.form.get('description'),
+ }
+ if contact().create(args[0], data) is True:
+ return redirect('/customer/'+ args[0] +'/dashboard')
+ else:
+ self.var['error_message'] = "There was an issue creating the contact."
+ return render_template('error.html', var=self.var)
+ elif self.request.path =='/customer/'+args[0]+'/contact/'+args[1]+'/update':
+ data = {
+ 'contact_id': args[1],
+ 'firstname': self.request.form.get('firstname'),
+ 'lastname': self.request.form.get('lastname'),
+ 'email': self.request.form.get('email'),
+ 'phonenumber': self.request.form.get('phonenumber'),
+ 'description': self.request.form.get('description'),
+ 'customer_id': args[0]
+ }
+ data['contact_id'] = args[1]
+ if contact().update(data) is True:
+ self.var['contact'] = contact().get(args[0], args[1])
+ self.var['contacts'] = contact().list_for_customer(args[0])
+ self.var['customer'] = customer().get(args[0])
+ return redirect('/customer/'+args[0]+'/dashboard')
+ else:
+ return render_template('error.html', var=self.var)
+
+ elif self.request.path =='/customer/'+args[0]+'/contact/'+args[1]+'/delete':
+ customer_id = args[0]
+ contact_id = args[1]
+ if contact().delete(customer_id, contact_id):
+ return redirect('/customer/'+args[0]+'/dashboard')
+ else:
+ self.var['error_message'] = "There was an issue deleting the contact."
+ return render_template('error.html', var=self.var)
+ else:
+ return render_template('error.html', var=self.var)
\ No newline at end of file
diff --git a/controller/customer.py b/controller/customer.py
index 1c03d01..1a9f4ed 100644
--- a/controller/customer.py
+++ b/controller/customer.py
@@ -9,17 +9,20 @@
import math
from decimal import Decimal
from flask import render_template,jsonify,redirect
+from flask import session
+
# Import custom modules.
from controller import root_web_controller
from model.customer import customer
-
+from model.contact import contact # Add this import
# Customer web controller.
class customer_web_controller(root_web_controller):
# HTTP GET method processor.
def get(self,*args,**kwargs):
+ user_id = self._get_authenticated_user_id()
if self.request.path=='/customers':
if self.request.args.get('count'):
customers = customer().count()
@@ -32,7 +35,7 @@ def get(self,*args,**kwargs):
else:
limit = 5
offset = (int(self.request.args.get('page'))*limit)-limit if self.request.args.get('page') else 0
- customers = customer().list(offset=offset,limit=limit)
+ customers = customer().list_for_user(user_id, offset=offset, limit=limit)
return jsonify({'status':'success','result':{'items':customers}})
elif self.request.path=='/customer/create':
return render_template('customer/create.html',var=self.var)
@@ -42,8 +45,14 @@ def get(self,*args,**kwargs):
return render_template('customer/update.html',var=self.var)
elif self.request.path=='/customer/'+args[0]+'/dashboard':
customer_id = args[0]
- self.var['customer'] = customer().get(customer_id)
- return render_template('customer/dashboard.html',var=self.var)
+ customer_data = customer().get(customer_id)
+ if customer_data and customer_data['user_id'] == user_id:
+ self.var['customer'] = customer_data
+ contacts = contact().list_for_customer(customer_id)
+ self.var['contacts'] = contacts
+ return render_template('customer/dashboard.html',var=self.var)
+ else:
+ return redirect('/login')
else:
return render_template('error.html',var=self.var)
@@ -57,7 +66,9 @@ def post(self,*args,**kwargs):
'website':self.request.form.get('website'),
'description':self.request.form.get('description')
}
- if customer().create(data) is True:
+ user_id = self._get_authenticated_user_id()
+ # if customer().create(data) is True:
+ if customer().create(data, user_id) is True:
return redirect('/dashboard')
else:
return render_template('error.html',var=self.var)
@@ -74,5 +85,28 @@ def post(self,*args,**kwargs):
return redirect('/dashboard')
else:
return render_template('error.html',var=self.var)
+
+ elif self.request.path == '/customer/' + args[0] + '/delete':
+ user_id = self._get_authenticated_user_id()
+ customer_id = args[0]
+ customer_data = customer().get(customer_id)
+ if customer_data and customer_data['user_id'] == user_id:
+ try:
+ if customer().delete(customer_id):
+ return jsonify({'status': 'success', 'message': 'Customer deleted successfully.', 'refresh': True})
+ else:
+ return jsonify({'status': 'failure', 'message': 'Failed to delete customer.'})
+ except Exception as e:
+ app.logger.error("Error occurred while deleting customer {}: {}".format(customer_id, str(e)))
+ return jsonify({'status': 'failure', 'message': "Error occurred while deleting customer: {}".format(str(e))})
+ else:
+ return jsonify({'status': 'failure', 'message': 'Customer not found or you do not have permission.'})
else:
return render_template('error.html',var=self.var)
+
+ def _get_authenticated_user_id(self):
+ user_id = session.get('user_id')
+ if not user_id:
+ return None
+ # raise Exception("User is not authenticated")
+ return user_id
\ No newline at end of file
diff --git a/controller/user.py b/controller/user.py
index d341ce8..29ebf03 100644
--- a/controller/user.py
+++ b/controller/user.py
@@ -6,18 +6,89 @@
##
# Import community modules.
-from flask import render_template
+from flask import render_template, redirect, request, flash, make_response, session
# Import custom modules.
from controller import root_web_controller
-
+from model.user import user
# User web controller.
class user_web_controller(root_web_controller):
# HTTP GET method processor.
- def get(self,*args,**kwargs):
- if self.request.path=='/dashboard':
- return render_template('user/dashboard.html',var=self.var)
+ def get(self, *args, **kwargs):
+ if self.request.path == '/login':
+ return render_template('user/login.html', var=self.var)
+ elif self.request.path == '/signup':
+ return render_template('user/signup.html', var=self.var)
+ elif self.request.path == '/dashboard':
+ user_id = self._get_authenticated_user_id()
+ if user_id:
+ user_data = user().get(user_id)
+ if user_data:
+ self.var['user'] = user_data
+ return render_template('user/dashboard.html', var=self.var)
+ return redirect('/login')
+ elif self.request.path == '/logout':
+ return self.logout()
else:
- return render_template('error.html',var=self.var)
+ return render_template('error.html', var=self.var)
+
+ # HTTP POST method processor.
+ def post(self):
+ if self.request.path == '/login':
+ username = self.request.form.get('username')
+ password = self.request.form.get('password')
+ user_model = user()
+ user_data = user_model.authenticate(username, password)
+
+ if user_data:
+ if user_model.authenticate(username, password):
+ session['user_id'] = user_data['id']
+ session['username'] = user_data['username']
+ return redirect('/dashboard')
+ else:
+ flash("Invalid username or password", "error")
+ self.var = {'static': {'endpoint': 'your_static_endpoint_url'}}
+ self.var['show_signup_link'] = True
+ return render_template('user/login.html', error="Invalid username or password", var=self.var)
+ else:
+ flash("Don't have an account? Sign up first.", "info")
+ return redirect('/login')
+ elif self.request.path == '/signup':
+ username = self.request.form.get('username')
+ email = self.request.form.get('email')
+ password = self.request.form.get('password')
+ confirm_password = self.request.form.get('confirm-password')
+ if password != confirm_password:
+ flash("Passwords do not match", "error")
+ return render_template('user/signup.html', error="Passwords do not match", var=self.var)
+ user_model = user()
+ user_id = user_model.create(username, password, email)
+ if user_id:
+ flash("Signup successful. Please login.", "success")
+ return redirect('/login')
+ else:
+ flash("Signup failed. Please try again.", "error")
+ return render_template('user/signup.html', error="Signup failed", var=self.var)
+ return render_template('error.html', var=self.var)
+
+
+ def _set_authenticated_user(self, user_id):
+ resp = make_response(redirect('/dashboard'))
+ resp.set_cookie('user_id', str(user_id), max_age=60*60*24*30)
+ return resp
+
+ def _get_authenticated_user_id(self):
+ user_id = self.request.cookies.get('user_id')
+ if user_id:
+ return user_id
+ user_id = session.get('user_id')
+ return user_id if user_id else None
+
+ # Method to handle logout
+ def logout(self):
+ resp = make_response(redirect('/login'))
+ resp.delete_cookie('user_id')
+ session.clear()
+ return resp
diff --git a/init.py b/init.py
index 9a95ce6..1581871 100644
--- a/init.py
+++ b/init.py
@@ -8,6 +8,7 @@
# Import community modules.
import sys
+
# Append App specific Python paths.
sys.path.append('model')
sys.path.append('controller')
@@ -15,18 +16,43 @@
# Import community modules.
import argparse
-from flask import Flask,request
+from flask import Flask,request, redirect, render_template
# Import custom modules.
from controller.user import user_web_controller
from controller.customer import customer_web_controller
from controller.contact import contact_web_controller
+from model.customer import customer
+from model.contact import contact
+from datetime import timedelta
+
# Health web controller.
def health_web_controller():
return str('OK')
+# Create user.
+def user_signup():
+ if request.method == 'GET':
+ return user_web_controller(request).get()
+ elif request.method == 'POST':
+ return user_web_controller(request).post()
+
+# User Signin route
+def user_login():
+ if request.method == 'GET':
+ return user_web_controller(request).get()
+ elif request.method == 'POST':
+ return user_web_controller(request).post()
+
+# User Logout route
+def user_logout():
+ if request.method == 'GET':
+ return user_web_controller(request).get()
+ else:
+ return None
+
# View dashboard.
def dashboard():
if request.method=='GET':
@@ -52,6 +78,13 @@ def update_customer(arg_0):
else:
return None
+# Delete customer.
+def delete_customer(arg_0):
+ if request.method == 'POST':
+ return customer_web_controller(request).post(str(arg_0))
+ else:
+ return None
+
# List customers.
def list_customers():
if request.method=='GET':
@@ -68,36 +101,58 @@ def create_contact(arg_0):
else:
return None
-# Update contact.
-def update_contact(arg_0,arg_1):
- if request.method=='GET':
- return contact_web_controller(request).get(str(arg_0),str(arg_1))
- elif request.method=='POST':
- return contact_web_controller(request).post(str(arg_0),str(arg_1))
+def update_contact(arg_0, arg_1):
+ print("Received Customer ID: {}, Contact ID: {}".format(arg_0, arg_1))
+ if request.method == 'GET':
+ return contact_web_controller(request).get(str(arg_0), str(arg_1))
+ elif request.method == 'POST':
+ return contact_web_controller(request).post(str(arg_0), str(arg_1))
else:
- return None
+ return None
# List contacts.
-def list_contacts():
+def list_contacts(arg_0):
if request.method=='GET':
- return contact_web_controller(request).get()
+ return contact_web_controller(request).get(str(arg_0))
+ else:
+ return None
+
+# Delete contact route
+def delete_contact(arg_0, arg_1):
+ if request.method == 'POST':
+ return contact_web_controller(request).post(str(arg_0),str(arg_1))
+ else:
+ return None
+
+
+def customer_dashboard(arg_0):
+ if request.method == 'GET':
+ return customer_web_controller(request).get(str(arg_0))
else:
return None
+
# Initialize Flask app.
app = Flask('CRM app',template_folder='view')
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False
+app.secret_key = 'sloopstash'
+app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=30)
# App routes.
app.add_url_rule('/health',view_func=health_web_controller)
+app.add_url_rule('/signup', view_func=user_signup, methods=['GET', 'POST'])
+app.add_url_rule('/login', view_func=user_login, methods=['GET', 'POST'])
+app.add_url_rule('/logout', view_func=user_logout, methods=['GET'])
app.add_url_rule('/dashboard',view_func=dashboard)
app.add_url_rule('/customer/create',view_func=create_customer,methods=['GET','POST'])
app.add_url_rule('/customer//update',view_func=update_customer,methods=['GET','POST'])
+app.add_url_rule('/customer//delete', view_func=delete_customer, methods=['POST'])
app.add_url_rule('/customers',view_func=list_customers)
app.add_url_rule('/customer//contact/create',view_func=create_contact,methods=['GET','POST'])
app.add_url_rule('/customer//contact//update',view_func=update_contact,methods=['GET','POST'])
-app.add_url_rule('/customer//contacts',view_func=list_contacts)
+app.add_url_rule('/customer//contact//delete', view_func=delete_contact, methods=['POST'])
+app.add_url_rule('/customer//dashboard', view_func=customer_dashboard, methods=['GET'])
if __name__=='__main__':
diff --git a/model/contact.py b/model/contact.py
index e69de29..6bf729b 100644
--- a/model/contact.py
+++ b/model/contact.py
@@ -0,0 +1,131 @@
+##
+# -*- coding: utf-8 -*-
+##
+##
+# Customer model.
+##
+
+# Import community modules.
+import json
+import logging
+
+# Import custom modules.
+from database import redis
+
+
+# Customer main model.
+class contact(object):
+
+ # Initializer.
+ def __init__(self):
+ self.redis = redis
+
+ def create(self, customer_id, data):
+ try:
+ contact_id = self.redis.engine.incr(
+ self.redis.conf['key_prefix']['contact']['counter']
+ )
+ contact_key = "customer:{}:contact:{}".format(customer_id, contact_id)
+ data['id'] = contact_id
+
+ for key, value in data.items():
+ self.redis.engine.hset(contact_key, key, value)
+
+ except Exception as error:
+ print("Error creating contact: {}".format(error))
+ return False
+ else:
+ print("Contact created successfully with ID {}".format(contact_id))
+ return True
+
+
+ # Update contact.
+ def update(self, data):
+ try:
+ contact_id = data['contact_id']
+ customer_id = data['customer_id']
+ contact_key = "customer:{}:contact:{}".format(customer_id, contact_id)
+ contact_data = self.redis.engine.hgetall(contact_key)
+ if not contact_data:
+ return False
+ for field, value in data.items():
+ self.redis.engine.hset(contact_key, field, value)
+ except Exception as error:
+ return False
+ else:
+ return True
+
+ # Get contact.
+ def get(self, customer_id, contact_id):
+ try:
+ key = "customer:{}:contact:{}".format(customer_id, contact_id)
+ data = self.redis.engine.hgetall(key)
+ if data:
+ item = {
+ 'id': contact_id
+ }
+ item.update(data)
+ return item
+ else:
+ return None
+ except redis.ConnectionError as e:
+ return None
+ except redis.RedisError as e:
+ return None
+ except Exception as e:
+ return None
+
+ # Count of contact.
+ def count(self):
+ count = self.redis.engine.hlen(
+ self.redis.conf['key_prefix']['contact']['main']
+ )
+ return count
+
+ # List customers.
+ def list(self,**kwargs):
+ offset = kwargs['offset'] if kwargs.has_key('offset') else 0
+ limit = kwargs['limit'] if kwargs.has_key('limit') else 5
+ data = self.redis.engine.hgetall(
+ self.redis.conf['key_prefix']['contact']['main']
+ )
+ items = []
+ for key,value in data.items():
+ item = {
+ 'id':key
+ }
+ item.update(json.loads(value))
+ items.append(item)
+ return items
+
+ # List for customers
+ def list_for_customer(self, customer_id):
+ try:
+ keys = self.redis.engine.keys("customer:{}:contact:*".format(customer_id))
+ print "Fetched keys for customer {}: {}".format(customer_id, keys)
+ if not keys:
+ return []
+ items = []
+ for key in keys:
+ contact_data = self.redis.engine.hgetall(key)
+ contact_id = key.split(":")[-1]
+ contact_data['id'] = contact_id
+ items.append(contact_data)
+ print "Returning contacts for customer {}: {}".format(customer_id, items)
+ return items
+ except Exception as e:
+ print("Error fetching contacts:", e)
+ return []
+
+ # Delete contact.
+ def delete(self, customer_id, contact_id):
+ try:
+ contact_key = "customer:{}:contact:{}".format(customer_id, contact_id)
+ if not self.redis.engine.exists(contact_key):
+ return False
+ self.redis.engine.delete(contact_key)
+ return True
+ except Exception as error:
+ return False
+
+
\ No newline at end of file
diff --git a/model/customer.py b/model/customer.py
index d3475fa..2f3f439 100644
--- a/model/customer.py
+++ b/model/customer.py
@@ -20,13 +20,14 @@ def __init__(self):
self.redis = redis
# Create customer.
- def create(self,data):
+ def create(self, data, user_id):
try:
- id = self.redis.engine.incr(
+ customer_id = self.redis.engine.incr(
self.redis.conf['key_prefix']['customer']['counter']
)
+ data['user_id'] = user_id
self.redis.engine.hset(
- self.redis.conf['key_prefix']['customer']['main'],id,json.dumps(data)
+ self.redis.conf['key_prefix']['customer']['main'], customer_id, json.dumps(data)
)
except Exception as error:
return False
@@ -34,16 +35,22 @@ def create(self,data):
return True
# Update customer.
- def update(self,data):
+ def update(self, data):
try:
- id = data['customer_id']
- self.redis.engine.hset(
- self.redis.conf['key_prefix']['customer']['main'],id,json.dumps(data)
- )
+ customer_id = data['customer_id']
+ existing_customer = self.redis.engine.hget(self.redis.conf['key_prefix']['customer']['main'], customer_id)
+ if existing_customer:
+ current_data = json.loads(existing_customer)
+ current_data.update(data)
+ self.redis.engine.hset(self.redis.conf['key_prefix']['customer']['main'], customer_id, json.dumps(current_data))
+ return True
+ else:
+ print("Customer with ID {} not found!".format(customer_id))
+ return False
except Exception as error:
+ print("Error updating customer: {}".format(error))
return False
- else:
- return True
+
# Get customer.
def get(self,id):
@@ -81,3 +88,26 @@ def list(self,**kwargs):
item.update(json.loads(value))
items.append(item)
return items
+
+ # List for user.
+ def list_for_user(self, user_id, **kwargs):
+ data = self.redis.engine.hgetall(self.redis.conf['key_prefix']['customer']['main'])
+ items = []
+ for key, value in data.items():
+ customer_data = json.loads(value)
+ if 'user_id' in customer_data and customer_data['user_id'] == user_id:
+ item = {'id': key}
+ item.update(customer_data)
+ items.append(item)
+ print("Items returned by list_for_user:", items)
+ return items
+
+ # Delete customer.
+ def delete(self, customer_id):
+ customer_key = self.redis.conf['key_prefix']['customer']['main']
+ if self.redis.engine.hexists(customer_key, customer_id):
+ self.redis.engine.hdel(customer_key, customer_id)
+ return True
+ else:
+ print("Customer {} does not exist.".format(customer_id))
+ return False
diff --git a/model/user.py b/model/user.py
index e69de29..1b659fa 100644
--- a/model/user.py
+++ b/model/user.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+##
+##
+# User model.
+##
+
+# Import community modules.
+import json
+
+# Import custom modules.
+from database import redis
+
+
+# User main model.
+class user(object):
+
+ # Initializer.
+ def __init__(self):
+ self.redis = redis
+
+ # Create user.
+ def create(self, username, password, email):
+ try:
+ user_data = {
+ 'username': username,
+ 'password': password,
+ 'email': email
+ }
+ user_id = self.redis.engine.incr(self.redis.conf['key_prefix']['user']['counter'])
+ self.redis.engine.hset(self.redis.conf['key_prefix']['user']['main'], user_id, json.dumps(user_data))
+ except Exception as error:
+ return False
+ else:
+ return user_id
+
+ # Authenticate user.
+ def authenticate(self, username, password):
+ for user_id in self.redis.engine.hkeys(self.redis.conf['key_prefix']['user']['main']):
+ user_data = json.loads(self.redis.engine.hget(self.redis.conf['key_prefix']['user']['main'], user_id))
+ if user_data['username'] == username and user_data['password'] == password:
+ return {'id': user_id, 'username': username}
+ return None
+
+ # Get user by ID.
+ def get(self, user_id):
+ user_data = self.redis.engine.hget(self.redis.conf['key_prefix']['user']['main'], user_id)
+ if user_data:
+ user_info = json.loads(user_data)
+ user_info['id'] = user_id
+ return user_info
+ return None
diff --git a/view/contact/create.html b/view/contact/create.html
index e69de29..5a167c7 100644
--- a/view/contact/create.html
+++ b/view/contact/create.html
@@ -0,0 +1,64 @@
+{% extends 'main.html' %}
+
+{% block title %}Create contact | SloopStash CRM{% endblock %}
+
+{% block content %}
+
+{% endblock %}
diff --git a/view/contact/update.html b/view/contact/update.html
index e69de29..ec41075 100644
--- a/view/contact/update.html
+++ b/view/contact/update.html
@@ -0,0 +1,64 @@
+{% extends 'main.html' %}
+
+{% block title %}Update contact | SloopStash CRM{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/view/customer/dashboard.html b/view/customer/dashboard.html
new file mode 100644
index 0000000..55ad386
--- /dev/null
+++ b/view/customer/dashboard.html
@@ -0,0 +1,147 @@
+{% extends 'main.html' %}
+
+{% block title %}Dashboard | SloopStash CRM{% endblock %}
+
+{% block content %}
+
+{% endblock %}
+
+{% block js %}
+
+{% endblock %}
diff --git a/view/main.html b/view/main.html
index d0f79ec..daba28b 100644
--- a/view/main.html
+++ b/view/main.html
@@ -24,7 +24,7 @@
+
+
Welcome, {{ var.user.username }}!
+
@@ -62,6 +65,45 @@
}
]
});
+
+ $(document).ready(function() {
+ $(document).on('click', '.delete-customer', function() {
+ var customerId = $(this).data('id');
+
+
+ if (confirm('Are you sure you want to delete this customer?')) {
+
+ deleteCustomer(customerId);
+ }
+ });
+});
+
+function deleteCustomer(customerId) {
+ $.ajax({
+ type: "POST",
+ url: "/customer/" + customerId + "/delete",
+ data: {
+ _method: 'DELETE'
+ },
+ dataType: 'json',
+ success: function(response) {
+ if (response.status === "success") {
+ alert(response.message);
+ if (response.refresh) {
+ location.reload();
+ } else {
+ $('#customer_' + customerId).remove();
+ }
+ } else {
+ alert(response.message);
+ }
+ },
+ error: function(xhr, status, error) {
+ alert("An error occurred while deleting the customer.");
+ }
+ });
+}
+
});
{% endblock %}
diff --git a/view/user/login.html b/view/user/login.html
new file mode 100644
index 0000000..b71a90c
--- /dev/null
+++ b/view/user/login.html
@@ -0,0 +1,53 @@
+{% extends 'main.html' %}
+
+{% block title %}Login | SloopStash CRM{% endblock %}
+
+{% block content %}
+
+
+
+
+
+ {% with messages = get_flashed_messages(with_categories=true) %}
+ {% if messages %}
+
+ {% for category, message in messages %}
+
+ {{ message }}
+
+ {% endfor %}
+
+ {% endif %}
+ {% endwith %}
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/view/user/signup.html b/view/user/signup.html
new file mode 100644
index 0000000..46e940e
--- /dev/null
+++ b/view/user/signup.html
@@ -0,0 +1,53 @@
+{% extends 'main.html' %}
+
+{% block title %}Sign Up | SloopStash CRM{% endblock %}
+
+{% block content %}
+
+{% endblock %}