Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -10,7 +10,6 @@ from fpdf import FPDF
|
|
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
|
@@ -18,7 +17,6 @@ def load_data():
|
|
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 |
|
@@ -37,14 +35,14 @@ def export_as_pdf(customer):
|
|
37 |
|
38 |
if customer["StitchingHistory"]:
|
39 |
pdf.cell(0, 10, "Stitching History:", ln=True)
|
40 |
-
for entry in customer["StitchingHistory"].split(" || "):
|
41 |
pdf.multi_cell(0, 10, f"- {entry}")
|
42 |
|
43 |
filename = f"Tailor_Record_{customer['SerialNo']}_{customer['Name']}.pdf"
|
44 |
pdf.output(filename)
|
45 |
return filename
|
46 |
|
47 |
-
#
|
48 |
st.set_page_config("Tailor Record App", layout="wide")
|
49 |
st.title("π Tailor Record Management System")
|
50 |
|
@@ -56,7 +54,6 @@ with st.form("new_customer"):
|
|
56 |
col1, col2 = st.columns(2)
|
57 |
with col1:
|
58 |
name = st.text_input("Customer Name*", max_chars=100)
|
59 |
-
# Phone number input that only accepts numbers
|
60 |
phone = st.text_input("Phone Number*", max_chars=15, key="phone_input")
|
61 |
with col2:
|
62 |
sizing_text = st.text_area("Sizing Details*", height=200)
|
@@ -104,126 +101,3 @@ with st.form("new_customer"):
|
|
104 |
save_data(df)
|
105 |
st.success("Customer record saved successfully.")
|
106 |
st.rerun()
|
107 |
-
|
108 |
-
# View Records
|
109 |
-
st.subheader("π Search & Manage Customer Records")
|
110 |
-
|
111 |
-
if not df.empty:
|
112 |
-
# Search functionality
|
113 |
-
search_term = st.text_input("Search by Name, Phone, or Serial No:")
|
114 |
-
if search_term:
|
115 |
-
search_mask = (
|
116 |
-
df['Name'].str.contains(search_term, case=False) |
|
117 |
-
df['Phone'].str.contains(search_term) |
|
118 |
-
df['SerialNo'].astype(str).str.contains(search_term)
|
119 |
-
filtered_df = df[search_mask]
|
120 |
-
else:
|
121 |
-
filtered_df = df
|
122 |
-
|
123 |
-
if filtered_df.empty:
|
124 |
-
st.info("No matching records found.")
|
125 |
-
else:
|
126 |
-
# Display all matching records in a table with select option
|
127 |
-
st.dataframe(
|
128 |
-
filtered_df[['SerialNo', 'Name', 'Phone']],
|
129 |
-
use_container_width=True,
|
130 |
-
hide_index=True
|
131 |
-
)
|
132 |
-
|
133 |
-
# Select customer to view/edit
|
134 |
-
selected_serial = st.selectbox(
|
135 |
-
"Select customer by Serial No to manage:",
|
136 |
-
filtered_df['SerialNo'],
|
137 |
-
format_func=lambda x: f"{x} - {filtered_df.loc[filtered_df['SerialNo'] == x, 'Name'].values[0]}"
|
138 |
-
)
|
139 |
-
|
140 |
-
selected_index = df[df['SerialNo'] == selected_serial].index[0]
|
141 |
-
customer = df.loc[selected_index]
|
142 |
-
|
143 |
-
st.markdown(f"### π Details for **{customer['Name']}** (Serial No: {customer['SerialNo']})")
|
144 |
-
st.write(f"**Phone:** {customer['Phone']}")
|
145 |
-
st.write(f"**Sizing Details:** {customer['SizingText']}")
|
146 |
-
|
147 |
-
if customer["ImagePath"] and os.path.exists(customer["ImagePath"]):
|
148 |
-
try:
|
149 |
-
st.image(customer["ImagePath"], caption="Sizing Image", use_column_width=True)
|
150 |
-
except Exception as e:
|
151 |
-
st.error(f"Error loading image: {e}")
|
152 |
-
|
153 |
-
if customer["StitchingHistory"]:
|
154 |
-
st.markdown("**π§΅ Stitching History:**")
|
155 |
-
for entry in customer["StitchingHistory"].split(" || "):
|
156 |
-
st.markdown(f"- {entry}")
|
157 |
-
|
158 |
-
col1, col2, col3 = st.columns(3)
|
159 |
-
with col1:
|
160 |
-
if st.button("π Edit Record"):
|
161 |
-
with st.form("update_form"):
|
162 |
-
updated_name = st.text_input("Name*", value=customer["Name"])
|
163 |
-
updated_phone = st.text_input("Phone*", value=customer["Phone"])
|
164 |
-
updated_sizing = st.text_area("Sizing Details*", value=customer["SizingText"], height=200)
|
165 |
-
|
166 |
-
# Handle existing stitching history
|
167 |
-
existing_history = customer["StitchingHistory"].split(" || ") if customer["StitchingHistory"] else []
|
168 |
-
st.markdown("**π§΅ Update Stitching History (Optional):**")
|
169 |
-
new_history_entries = []
|
170 |
-
with st.expander("Edit History Entries"):
|
171 |
-
num_entries = st.number_input("Number of entries", min_value=0, max_value=10, step=1, value=len(existing_history))
|
172 |
-
for i in range(num_entries):
|
173 |
-
if i < len(existing_history):
|
174 |
-
date_part, desc_part = existing_history[i].split(" - ", 1) if " - " in existing_history[i] else (existing_history[i], "")
|
175 |
-
try:
|
176 |
-
default_date = datetime.strptime(date_part, "%Y-%m-%d").date()
|
177 |
-
except:
|
178 |
-
default_date = datetime.now().date()
|
179 |
-
default_desc = desc_part
|
180 |
-
else:
|
181 |
-
default_date = datetime.now().date()
|
182 |
-
default_desc = ""
|
183 |
-
|
184 |
-
date = st.date_input(f"Stitch Date {i+1}", value=default_date, key=f"update_date_{i}")
|
185 |
-
desc = st.text_input(f"Description (optional) for Stitch {i+1}", value=default_desc, key=f"update_desc_{i}")
|
186 |
-
new_history_entries.append(f"{date} - {desc}")
|
187 |
-
|
188 |
-
submitted_update = st.form_submit_button("Update Now")
|
189 |
-
if submitted_update:
|
190 |
-
if not updated_name or not updated_phone or not updated_phone.isdigit() or not updated_sizing:
|
191 |
-
st.error("Name, valid phone number, and sizing details are required.")
|
192 |
-
else:
|
193 |
-
df.at[selected_index, "Name"] = updated_name.strip()
|
194 |
-
df.at[selected_index, "Phone"] = updated_phone.strip()
|
195 |
-
df.at[selected_index, "SizingText"] = updated_sizing.strip()
|
196 |
-
df.at[selected_index, "StitchingHistory"] = " || ".join(new_history_entries) if new_history_entries else ""
|
197 |
-
save_data(df)
|
198 |
-
st.success("Record updated successfully.")
|
199 |
-
st.rerun()
|
200 |
-
|
201 |
-
with col2:
|
202 |
-
if st.button("ποΈ Delete Record"):
|
203 |
-
st.warning("Are you sure you want to delete this record?")
|
204 |
-
if st.button("β
Confirm Delete"):
|
205 |
-
if customer["ImagePath"] and os.path.exists(customer["ImagePath"]):
|
206 |
-
try:
|
207 |
-
os.remove(customer["ImagePath"])
|
208 |
-
except Exception as e:
|
209 |
-
st.error(f"Error deleting image: {e}")
|
210 |
-
df = df.drop(index=selected_index).reset_index(drop=True)
|
211 |
-
save_data(df)
|
212 |
-
st.success("Record deleted successfully.")
|
213 |
-
st.rerun()
|
214 |
-
|
215 |
-
with col3:
|
216 |
-
if st.button("π€ Export as PDF"):
|
217 |
-
try:
|
218 |
-
filename = export_as_pdf(customer.to_dict())
|
219 |
-
with open(filename, "rb") as f:
|
220 |
-
st.download_button(
|
221 |
-
"β¬οΈ Download PDF",
|
222 |
-
f,
|
223 |
-
file_name=os.path.basename(filename),
|
224 |
-
mime="application/pdf"
|
225 |
-
)
|
226 |
-
except Exception as e:
|
227 |
-
st.error(f"Error generating PDF: {e}")
|
228 |
-
else:
|
229 |
-
st.info("No customer records found.")
|
|
|
10 |
def load_data():
|
11 |
if os.path.exists("data.csv"):
|
12 |
df = pd.read_csv("data.csv")
|
|
|
13 |
if 'SerialNo' not in df.columns:
|
14 |
df['SerialNo'] = range(1, len(df)+1)
|
15 |
return df
|
|
|
17 |
|
18 |
# Save data
|
19 |
def save_data(df):
|
|
|
20 |
df['SerialNo'] = range(1, len(df)+1)
|
21 |
df.to_csv("data.csv", index=False)
|
22 |
|
|
|
35 |
|
36 |
if customer["StitchingHistory"]:
|
37 |
pdf.cell(0, 10, "Stitching History:", ln=True)
|
38 |
+
for entry in str(customer["StitchingHistory"]).split(" || "):
|
39 |
pdf.multi_cell(0, 10, f"- {entry}")
|
40 |
|
41 |
filename = f"Tailor_Record_{customer['SerialNo']}_{customer['Name']}.pdf"
|
42 |
pdf.output(filename)
|
43 |
return filename
|
44 |
|
45 |
+
# UI Starts
|
46 |
st.set_page_config("Tailor Record App", layout="wide")
|
47 |
st.title("π Tailor Record Management System")
|
48 |
|
|
|
54 |
col1, col2 = st.columns(2)
|
55 |
with col1:
|
56 |
name = st.text_input("Customer Name*", max_chars=100)
|
|
|
57 |
phone = st.text_input("Phone Number*", max_chars=15, key="phone_input")
|
58 |
with col2:
|
59 |
sizing_text = st.text_area("Sizing Details*", height=200)
|
|
|
101 |
save_data(df)
|
102 |
st.success("Customer record saved successfully.")
|
103 |
st.rerun()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|