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 %} +
+
+
+
+
+
+

Create contact

+
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + + Cancel +
+
+ +
+
+
+
+{% 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 %} +
+
+
+
+
+
+

Update contact for + {{ var.customer.name if var.customer else 'Unknown Customer' }}

+
+
+
+
+
+
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + + +
+ +
+
+ + +
+
+ + Cancel + +
+ +
+
+
+
+{% 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 %} +
+
+ +
+
+
+
+
+

+ + + + Contacts for {{ var.customer.name }} +

+
+ +
+
+ + + + +
+ + + + + + + + + + + + + {% for contact in var.contacts %} + + + + + + + + + {% else %} + + + + {% endfor %} + +
FirstNameLastNameEmailPhonenumberDescriptionActions
{{ contact.firstname }}{{ contact.lastname }}{{ contact.email }}{{ contact.phonenumber }}{{ contact.description }} +
+ + + +
+ + +
+
+
No contacts found for this customer.
+
+ +
+
+
+
+{% 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 %} +
+
+
+
+
+
+

Login

+
+
+
+ {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} +
+ {% for category, message in messages %} +
+ {{ message }} +
+ {% endfor %} +
+ {% endif %} + {% endwith %} + +
+
+
+
+ + +
+
+
+
+ + +
+
+ + Don't have an account? Sign Up +
+
+ +
+
+
+
+{% 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 %} +
+
+
+
+
+
+

Sign Up

+
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+ + Already have an account? Login +
+
+ +
+
+
+
+{% endblock %}