File size: 11,442 Bytes
23da334
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
import streamlit as st
import google.generativeai as genai
import textwrap  # For wrapping long text

# --- API Key Setup (Replace with your actual keys) ---
API_KEYS = [
    "AIzaSyCnvlaZII4rP6UUy9LHL2u5Ab7CpST7U9g",
    "AIzaSyBXg8nVnRCrLcbBTby7j5yDoKaQvfo9rFk",
    "AIzaSyCbPsdkZ8DGCAOSlfrXhh5JP2OLYEDHcJg"
]

# --- Helper Functions ---
def call_gemini_api(prompt):
    for api_key in API_KEYS:
        try:
            genai.configure(api_key=api_key)
            model = genai.GenerativeModel("gemini-pro")
            response = model.generate_content(prompt)
            return response.text.strip()
        except Exception as e:
            error_message = str(e)
            if "insufficient_quota" in error_message or "Quota exceeded" in error_message:
                continue
            else:
                return f"❌ เกิดข้อผิดพลาด: {error_message}"
    return "⚠️ API ทั้งหมดหมดโควต้าแล้ว กรุณาตรวจสอบบัญชีของคุณ"

def process_menus(response_text):
    menu_list = response_text.split("🍽️ เมนูที่")
    menu_list = [menu.strip() for menu in menu_list if menu.strip()]
    if not menu_list:
        menu_list = response_text.split("\n- ")
        menu_list = [menu.strip() for menu in menu_list if menu.strip()]
    if not menu_list:
        menu_list = response_text.split("\n• ")
        menu_list = [menu.strip() for menu in menu_list if menu.strip()]
    return menu_list

# --- Custom CSS ---
st.markdown("""

<style>

/* Global Styles */

body {

    font-family: 'Kanit', sans-serif; /* Modern Thai font */

}



.stApp {

    background-color: #f0f2f6;  /* Light gray background */

    background-image: url("https://www.transparenttextures.com/patterns/subtle-white-feathers.png"); /*Subtle Background Pattern*/



}



/* Header */

.title {

    color: #2c3e50;

    text-align: center;

    padding: 1rem 0;

    font-size: 2.5rem; /* Larger title */

    font-weight: 600;  /* Semi-bold */

}



/* Mode Selection */

.mode-selection {

    margin-bottom: 2rem;

    border-radius: 10px;

    padding: 10px;

    background-color: white;

    box-shadow: 0 4px 8px rgba(0,0,0,0.1);

}



/* Input Sections */

.input-section {

    background-color: white;

    padding: 20px;

    border-radius: 10px;

    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);

    margin-bottom: 20px;

}



/* Input Fields */

.stTextInput, .stSelectbox, .stSlider, .stRadio, .stNumberInput {

    margin-bottom: 10px;

}

.stTextArea>div>div>textarea{

    border-color:#3498db;

}



/* Buttons */

.stButton>button {

    background-color: #3498db; /* Blue */

    color: white;

    border: none;

    border-radius: 20px; /* Rounded buttons */

    padding: 10px 24px;

    font-size: 1.1rem;

    transition: all 0.3s ease;

    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* Subtle shadow */

    width: 100%; /* Make buttons full width */

}



.stButton>button:hover {

    background-color: #2980b9; /* Darker blue on hover */

    transform: translateY(-2px); /* Slight lift on hover */

    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);

}



.stButton>button:active {

    transform: translateY(0); /* Reset position on click */

    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);

}



/* Menu Columns */

.menu-column {

    background-color: white;

    border-radius: 10px;

    padding: 20px;

    margin-bottom: 20px;

    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);

    transition: transform 0.2s ease; /* Smooth transition */

    border: 2px solid transparent; /* Add a border */

}



.menu-column:hover {

    transform: scale(1.03); /* Slightly enlarge on hover */

    border-color: #3498db;

}



.menu-column h3 {

    color: #3498db; /* Blue heading */

    margin-bottom: 10px;

    font-size: 1.4rem;

}



.menu-item {

    font-size: 1rem;

    line-height: 1.6;

    color: #4a4a4a; /* Dark gray text */

}



/* Expander */

.st-expanderHeader {

    font-size: 1.2rem;

    font-weight: 500; /* Slightly bolder expander header */

}



/* About Section */

.about-section {

    background-color: #e0e0e0;

    border-radius: 10px;

    padding: 20px;

    margin-top: 20px;

}

.about-section ul {

    list-style: none; /* Remove bullet points */

    padding: 0;



}



.about-section li {

    margin-bottom: .5rem;

}



/* Spinners */

.st-cf {

    color: #3498db !important; /* Make spinners blue */

}



</style>

""", unsafe_allow_html=True)

# --- App UI ---
st.markdown("<h1 class='title'>🍽️ Smart Cooking App 😎</h1>", unsafe_allow_html=True)

with st.container(border=True):
    option = st.radio("🔹 เลือกโหมด:", ["สร้างเมนูจากวัตถุดิบ", "ค้นหาเมนูสำหรับซื้อ"],
                    horizontal=True, key="mode_select")

if option == "สร้างเมนูจากวัตถุดิบ":
    st.subheader("✨ สร้างเมนูแบบกำหนดเอง")

    with st.expander("📝 กรอกวัตถุดิบของคุณ", expanded=True):
        ingredients = st.text_area("วัตถุดิบ (คั่นด้วยจุลภาค):",
                                    placeholder="เช่น ไข่, หมูสับ, ผักกาด...",
                                    height=120)

    with st.expander("⚙️ ปรับแต่งเมนูของคุณ", expanded=False):
        col1, col2 = st.columns(2)
        with col1:
            num_ingredients = st.number_input("จำนวนวัตถุดิบหลัก", min_value=1, max_value=20, value=3, step=1)
            category = st.selectbox("ประเภทอาหาร",
                                    ["อาหารทั่วไป", "มังสวิรัติ", "อาหารคลีน", "อาหารไทย", "อาหารญี่ปุ่น", "อาหารตะวันตก"])
            calories = st.slider("แคลอรี่ที่ต้องการ (kcal)", 100, 1500, 500, step=50)

        with col2:
            difficulty = st.radio("ระดับความยาก", ["ง่าย", "ปานกลาง", "ยาก"], horizontal=True)
            cook_time = st.slider("เวลาทำอาหาร (นาที)", 5, 180, 30, step=5)

    if st.button("🍳 สร้างเมนู", use_container_width=True):
        if ingredients:
            prompt = (f"ฉันมี: {ingredients} ({num_ingredients} วัตถุดิบหลัก) "
                      f"แนะนำเมนู {category} เวลาทำไม่เกิน {cook_time} นาที "
                      f"ประมาณ {calories} kcal ระดับความยาก {difficulty} "
                      f"พร้อมวิธีทำอย่างละเอียด เสนอ 3 ตัวเลือก คั่นด้วย '🍽️ เมนูที่'")
            with st.spinner("กำลังสร้างสรรค์ไอเดียอร่อยๆ..."):
                menu_list = process_menus(call_gemini_api(prompt))

            if menu_list:
                st.subheader("🧑‍🍳 เมนูแนะนำ:")
                cols = st.columns(3)
                for i, menu in enumerate(menu_list[:3]):
                    with cols[i]:
                        st.markdown(f"<div class='menu-column'><h3>🍽️ เมนูที่ {i+1}</h3><p class='menu-item'>{menu}</p></div>", unsafe_allow_html=True)
            else:
                st.warning("⚠️ ไม่พบเมนูที่ตรงกับเกณฑ์ของคุณ โปรดลองปรับการตั้งค่า")
        else:
            st.warning("⚠️ กรุณากรอกวัตถุดิบของคุณ")

elif option == "ค้นหาเมนูสำหรับซื้อ":
    st.subheader("✨ ค้นหาเมนูที่ใช่สำหรับคุณ")

    with st.expander("⚙️ ตั้งค่าการค้นหา", expanded=True):
        col1, col2 = st.columns(2)
        with col1:
            country = st.selectbox("ประเทศ", ["ไทย", "ญี่ปุ่น", "เกาหลีใต้", "สหรัฐอเมริกา", "อังกฤษ", "ฝรั่งเศส", "เยอรมนี"])
            category = st.selectbox("ประเภทอาหาร", ["อาหารไทย", "อาหารญี่ปุ่น", "อาหารเกาหลี", "ฟาสต์ฟู้ด", "อาหารสุขภาพ"])
        with col2:
            taste = st.radio("รสชาติ", ["เผ็ด", "หวาน", "เค็ม", "เปรี้ยว"], horizontal=True)
            budget = st.radio("งบประมาณ", ["ต่ำกว่า 100 บาท", "100 - 300 บาท", "มากกว่า 300 บาท"], horizontal=True)

    if st.button("🔎 ค้นหาเมนู", use_container_width=True):
        prompt = (f"ฉันต้องการซื้ออาหาร {category} รสชาติ {taste} งบประมาณ {budget} ใน {country} "
                  f"แนะนำ 3 ตัวเลือกเมนู {category} ที่มีขายใน {country} คั่นด้วย '🍽️ เมนูที่'")

        with st.spinner("กำลังค้นหาตัวเลือกที่ดีที่สุด..."):
            menu_list = process_menus(call_gemini_api(prompt))

        if menu_list:
            st.subheader("🧑‍🍳 เมนูแนะนำ:")
            cols = st.columns(3)
            for i, menu in enumerate(menu_list[:3]):
                with cols[i]:
                     st.markdown(f"<div class='menu-column'><h3>🍽️ เมนูที่ {i+1}</h3><p class='menu-item'>{menu}</p></div>", unsafe_allow_html=True)
        else:
            st.warning("⚠️ ไม่พบเมนู โปรดลองอีกครั้ง")

# --- About Section ---
st.markdown("---")
if st.button("📜 เกี่ยวกับผู้พัฒนา", use_container_width=True):
    with st.expander("🤝 พบกับทีมงาน"):
        st.markdown("""

        <div class='about-section'>

        <ul>

        <li><strong>1. นาย กัลปพฤกษ์ วิเชียรรัตน์</strong> - <em>ชั้น 6/13 เลขที่ 3(คนแบกครับอิๆ)</em></li>

        <li><strong>2. นาย ธีราธร มุกดาเพชรรัตน์</strong> - <em>ชั้น 6/13 เลขที่ 13</em></li>

        <li><strong>3. นาย อภิวิชญ์ อดุลธรรมวิทย์</strong> - <em>ชั้น 6/13 เลขที่ 28</em></li>

        <li><strong>4. นาย ปัณณวิชญ์ หลีกภัย</strong> - <em>ชั้น 6/13 เลขที่ 29</em></li>

        </ul>

        </div>

        """, unsafe_allow_html=True)