engrharis commited on
Commit
9e6f4ea
Β·
verified Β·
1 Parent(s): dfb2015

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +194 -0
app.py ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import os
4
+ import re
5
+ from datetime import datetime
6
+ from PIL import Image
7
+ from fpdf import FPDF
8
+
9
+ # Load data
10
+ def load_data():
11
+ if os.path.exists("data.csv"):
12
+ df = pd.read_csv("data.csv")
13
+ # Ensure all records have a SerialNo
14
+ if 'SerialNo' not in df.columns:
15
+ df['SerialNo'] = range(1, len(df)+1)
16
+ return df
17
+ return pd.DataFrame(columns=["SerialNo", "Name", "Phone", "SizingText", "ImagePath", "StitchingHistory"])
18
+
19
+ # Save data
20
+ def save_data(df):
21
+ # Ensure SerialNo is continuous
22
+ df['SerialNo'] = range(1, len(df)+1)
23
+ df.to_csv("data.csv", index=False)
24
+
25
+ # Export customer record as PDF
26
+ def export_as_pdf(customer):
27
+ pdf = FPDF()
28
+ pdf.add_page()
29
+ pdf.set_font("Arial", size=12)
30
+
31
+ pdf.cell(200, 10, txt="Tailor Record", ln=True, align="C")
32
+ pdf.ln(10)
33
+ for key, value in customer.items():
34
+ if key == "ImagePath" and value and os.path.exists(value):
35
+ continue # Skip image path in PDF text
36
+ pdf.multi_cell(0, 10, f"{key}: {value}")
37
+ filename = f"{customer['Name']}_record.pdf"
38
+ pdf.output(filename)
39
+ return filename
40
+
41
+ # Initialize app
42
+ st.set_page_config("Tailor Record App", layout="wide")
43
+ st.title("πŸ‘” Tailor Record Management System")
44
+
45
+ df = load_data()
46
+
47
+ # Add Record
48
+ st.subheader("βž• Add New Customer Record")
49
+ with st.form("new_customer"):
50
+ col1, col2 = st.columns(2)
51
+ with col1:
52
+ name = st.text_input("Customer Name*", max_chars=100)
53
+ # Phone number input that only accepts numbers
54
+ phone = st.text_input("Phone Number*", max_chars=15, key="phone_input")
55
+ with col2:
56
+ sizing_text = st.text_area("Sizing Details*", height=200)
57
+ image = st.file_uploader("Optional: Upload sizing photo", type=["png", "jpg", "jpeg"])
58
+
59
+ st.markdown("**Stitching History (Optional):**")
60
+ history_entries = []
61
+ with st.expander("βž• Add Stitching History Entries (Optional)"):
62
+ num_entries = st.number_input("Number of entries", min_value=0, max_value=10, step=1)
63
+ for i in range(num_entries):
64
+ date = st.date_input(f"Stitch Date {i+1}", key=f"date_{i}")
65
+ desc = st.text_input(f"Description (optional) for Stitch {i+1}", key=f"desc_{i}")
66
+ history_entries.append(f"{date} - {desc}")
67
+
68
+ submitted = st.form_submit_button("πŸ’Ύ Save Record")
69
+
70
+ if submitted:
71
+ if not name or not phone or not phone.isdigit():
72
+ st.error("Customer Name and valid Phone Number are required!")
73
+ elif not sizing_text:
74
+ st.error("Sizing details are required!")
75
+ else:
76
+ image_path = ""
77
+ if image:
78
+ os.makedirs("images", exist_ok=True)
79
+ image_path = f"images/{datetime.now().strftime('%Y%m%d%H%M%S')}_{image.name}"
80
+ with open(image_path, "wb") as f:
81
+ f.write(image.getbuffer())
82
+ new_record = {
83
+ "SerialNo": len(df) + 1,
84
+ "Name": name.strip(),
85
+ "Phone": phone.strip(),
86
+ "SizingText": sizing_text.strip(),
87
+ "ImagePath": image_path,
88
+ "StitchingHistory": " || ".join(history_entries) if history_entries else ""
89
+ }
90
+ df = pd.concat([df, pd.DataFrame([new_record])], ignore_index=True)
91
+ df = df.sort_values(by="Name").reset_index(drop=True)
92
+ save_data(df)
93
+ st.success("Customer record saved successfully.")
94
+ st.experimental_rerun()
95
+
96
+ # View Records
97
+ st.subheader("πŸ” Search & Manage Customer Records")
98
+
99
+ if not df.empty:
100
+ # Search functionality
101
+ search_term = st.text_input("Search by Name, Phone, or Serial No:")
102
+ if search_term:
103
+ search_mask = (
104
+ df['Name'].str.contains(search_term, case=False) |
105
+ df['Phone'].str.contains(search_term) |
106
+ df['SerialNo'].astype(str).str.contains(search_term)
107
+ )
108
+ filtered_df = df[search_mask]
109
+ else:
110
+ filtered_df = df
111
+
112
+ if filtered_df.empty:
113
+ st.info("No matching records found.")
114
+ else:
115
+ # Display all matching records in a table with select option
116
+ st.dataframe(
117
+ filtered_df[['SerialNo', 'Name', 'Phone']],
118
+ use_container_width=True,
119
+ hide_index=True
120
+ )
121
+
122
+ # Select customer to view/edit
123
+ selected_serial = st.selectbox(
124
+ "Select customer by Serial No to manage:",
125
+ filtered_df['SerialNo'],
126
+ format_func=lambda x: f"{x} - {filtered_df.loc[filtered_df['SerialNo'] == x, 'Name'].values[0]}"
127
+ )
128
+
129
+ selected_index = df[df['SerialNo'] == selected_serial].index[0]
130
+ customer = df.loc[selected_index]
131
+
132
+ st.markdown(f"### πŸ“„ Details for **{customer['Name']}** (Serial No: {customer['SerialNo']})")
133
+ st.write(f"**Phone:** {customer['Phone']}")
134
+ st.write(f"**Sizing Text:** {customer['SizingText']}")
135
+
136
+ if customer["ImagePath"] and os.path.exists(customer["ImagePath"]):
137
+ st.image(customer["ImagePath"], caption="Sizing Image", use_column_width=True)
138
+
139
+ if customer["StitchingHistory"]:
140
+ st.markdown("**🧡 Stitching History:**")
141
+ for entry in customer["StitchingHistory"].split(" || "):
142
+ st.markdown(f"- {entry}")
143
+
144
+ col1, col2, col3 = st.columns(3)
145
+ with col1:
146
+ if st.button("πŸ“ Edit Record"):
147
+ with st.form("update_form"):
148
+ updated_name = st.text_input("Name*", value=customer["Name"])
149
+ updated_phone = st.text_input("Phone*", value=customer["Phone"])
150
+ updated_sizing = st.text_area("Sizing Details*", value=customer["SizingText"], height=200)
151
+
152
+ # Handle existing stitching history
153
+ existing_history = customer["StitchingHistory"].split(" || ") if customer["StitchingHistory"] else []
154
+ st.markdown("**🧡 Update Stitching History (Optional):**")
155
+ new_history_entries = []
156
+ with st.expander("Edit History Entries"):
157
+ num_entries = st.number_input("Number of entries", min_value=0, max_value=10, step=1, value=len(existing_history))
158
+ for i in range(num_entries):
159
+ default_date, default_desc = (existing_history[i].split(" - ", 1) if i < len(existing_history) else (datetime.now().date(), ""))
160
+ date = st.date_input(f"Stitch Date {i+1}", value=datetime.strptime(default_date, "%Y-%m-%d").date() if isinstance(default_date, str) else default_date, key=f"update_date_{i}")
161
+ desc = st.text_input(f"Description (optional) for Stitch {i+1}", value=default_desc, key=f"update_desc_{i}")
162
+ new_history_entries.append(f"{date} - {desc}")
163
+
164
+ submitted_update = st.form_submit_button("Update Now")
165
+ if submitted_update:
166
+ if not updated_name or not updated_phone or not updated_phone.isdigit() or not updated_sizing:
167
+ st.error("Name, valid phone number, and sizing details are required.")
168
+ else:
169
+ df.at[selected_index, "Name"] = updated_name.strip()
170
+ df.at[selected_index, "Phone"] = updated_phone.strip()
171
+ df.at[selected_index, "SizingText"] = updated_sizing.strip()
172
+ df.at[selected_index, "StitchingHistory"] = " || ".join(new_history_entries) if new_history_entries else ""
173
+ save_data(df)
174
+ st.success("Record updated successfully.")
175
+ st.experimental_rerun()
176
+
177
+ with col2:
178
+ if st.button("πŸ—‘οΈ Delete Record"):
179
+ st.warning("Are you sure you want to delete this record?")
180
+ if st.button("Confirm Delete"):
181
+ if customer["ImagePath"] and os.path.exists(customer["ImagePath"]):
182
+ os.remove(customer["ImagePath"])
183
+ df = df.drop(index=selected_index).reset_index(drop=True)
184
+ save_data(df)
185
+ st.success("Record deleted successfully.")
186
+ st.experimental_rerun()
187
+
188
+ with col3:
189
+ if st.button("πŸ“€ Export as PDF"):
190
+ filename = export_as_pdf(customer.to_dict())
191
+ with open(filename, "rb") as f:
192
+ st.download_button("Download PDF", f, file_name=filename)
193
+ else:
194
+ st.info("No customer records found.")