diff --git a/README.md b/README.md
new file mode 100644
index 0000000..00fcf74
--- /dev/null
+++ b/README.md
@@ -0,0 +1,134 @@
+# NutriPlan - Supabase & Stripe Integration
+
+This project is a sample implementation of a web application named NutriPlan. It demonstrates how to integrate Supabase for user authentication and database operations (managing orders) and Stripe for handling payments (subscriptions via Stripe Checkout).
+
+The frontend is built with plain HTML, CSS, and JavaScript, focusing on a clean, modern, and mobile-first design.
+
+## Features
+
+* **User Authentication:** Sign-up, login, and logout functionality managed by Supabase Auth.
+* **Product Display:** A clean, responsive grid displaying available subscription plans.
+* **Stripe Checkout:** Secure payment processing through redirection to Stripe Checkout.
+* **Order History:** Logged-in users can view their past orders, fetched from a Supabase database.
+* **Secure API Calls:** The architecture is designed to use a serverless backend (like Supabase Edge Functions) to securely create Stripe Checkout sessions, preventing keys from being exposed on the client-side.
+
+## Tech Stack
+
+* **Frontend:** HTML, CSS, JavaScript
+* **Authentication & Database:** [Supabase](https://supabase.io/)
+* **Payments:** [Stripe](https://stripe.com/)
+* **Fonts:** Google Fonts (Montserrat & Open Sans)
+
+## Project Structure
+
+```
+.
+├── index.html # The main HTML file for the user interface.
+├── style.css # The stylesheet for the application.
+├── script.js # The core JavaScript file for all client-side logic.
+└── README.md # This documentation file.
+```
+
+---
+
+## Installation and Setup
+
+Follow these instructions to get the project running locally.
+
+### Prerequisites
+
+* A [Supabase](https://app.supabase.io/) account.
+* A [Stripe](https://dashboard.stripe.com/register) account.
+* A local web server to serve the files (e.g., VS Code Live Server, Python's `http.server`).
+
+### Step 1: Set up Supabase
+
+1. **Create a New Project:**
+ * Go to your Supabase dashboard and create a new project.
+
+2. **Get API Keys:**
+ * Navigate to your project's **Settings > API**.
+ * You will need the **Project URL** and the **`anon` public key**.
+
+3. **Create an `orders` Table:**
+ * Go to the **Table Editor** in your Supabase project.
+ * Create a new table named `orders`.
+ * Add the following columns:
+ * `id` (int8, is identity) - Primary Key
+ * `created_at` (timestamptz, default `now()`)
+ * `user_id` (uuid, foreign key to `auth.users.id`) - This links the order to a user.
+ * `product_name` (text) - The name of the purchased plan.
+ * `stripe_payment_intent` (text) - The payment intent ID from Stripe for reference.
+ * Make sure to **disable Row Level Security (RLS)** for this table for initial testing, or create appropriate policies for access. For production, you should enable RLS and create policies that only allow users to see their own orders.
+
+### Step 2: Set up Stripe
+
+1. **Get API Keys:**
+ * Go to your Stripe Dashboard.
+ * Navigate to **Developers > API keys**.
+ * You will need the **Publishable key** (`pk_test_...`).
+
+2. **Create Products:**
+ * In the Stripe Dashboard, go to the **Products** catalog.
+ * Create at least two products (e.g., "Basic Plan", "Premium Plan").
+ * For each product, add a pricing plan (e.g., $9.99/month).
+ * Note down the **API ID** for each price (e.g., `price_123abc`). You will need this for the checkout button in `index.html`.
+
+### Step 3: Configure the Project
+
+1. **Clone or Download the Repository:**
+ * Get the project files onto your local machine.
+
+2. **Update `index.html`:**
+ * Open `index.html`.
+ * Find the `.product-card` divs.
+ * Update the `data-product-id` attribute with the **Price API IDs** you got from Stripe.
+ ```html
+
+ ```
+
+3. **Update `script.js`:**
+ * Open `script.js`.
+ * At the top of the file, replace the placeholder constants with your actual keys from Supabase and Stripe.
+ ```javascript
+ const SUPABASE_URL = 'YOUR_SUPABASE_URL'; // From Supabase Settings > API
+ const SUPABASE_ANON_KEY = 'YOUR_SUPABASE_ANON_KEY'; // From Supabase Settings > API
+ const STRIPE_PUBLISHABLE_KEY = 'YOUR_STRIPE_PUBLISHABLE_KEY'; // From Stripe Developers > API Keys
+ ```
+
+### Step 4: (Advanced) Create the Backend Function
+
+For the Stripe Checkout to work, you need a secure backend environment to create the checkout session. The client-side code in `script.js` is prepared to call a serverless function.
+
+1. **Create a Supabase Edge Function:**
+ * Use the Supabase CLI to create a new function (e.g., `create-checkout-session`).
+ * This function will receive a `productId` from the client.
+ * Inside the function, use the Stripe Node.js library to create a checkout session. You will need your **Stripe Secret Key** here (store it as a Supabase secret).
+ * The function should return the `sessionId` to the client.
+
+2. **Client-side Call:**
+ * In `script.js`, uncomment and use the `supabase.functions.invoke` call to trigger your edge function.
+
+---
+
+## Testing
+
+1. **Start a Local Server:**
+ * From the project's root directory, start a simple web server. For example, if you have Python 3:
+ ```bash
+ python -m http.server
+ ```
+ * Open your browser and navigate to `http://localhost:8000` (or the appropriate port).
+
+2. **Test Authentication:**
+ * Since the example uses a dummy login, you'll need to either implement a full Supabase Auth UI or manually create a user in your Supabase dashboard and log in via the browser console to get a session.
+ * Once logged in, your email should appear, and the "Your Orders" section should be visible.
+
+3. **Test Checkout:**
+ * Click on a "Choose Plan" button.
+ * Check the browser's console. You should see a log message indicating a redirect would happen.
+ * If you have implemented the Supabase Edge Function, you should be redirected to the Stripe Checkout page.
+
+4. **Test Order History:**
+ * After a successful (test) payment, you'll need a mechanism (like a Stripe webhook) to write the order details back to your Supabase `orders` table.
+ * Once an order is in the table for the logged-in user, it should appear in the "Your Orders" section.
\ No newline at end of file
diff --git a/index.html b/index.html
index d2b0850..2ebc0c9 100644
--- a/index.html
+++ b/index.html
@@ -1,121 +1,63 @@
-
+
- NutriPlan - Программа 'Фитнес'
+ NutriPlan - Your Personal Meal Plan
+
-
-
+
-
-
-
+
+
NutriPlan
+
+
-
-
-
-
Программа питания 'Фитнес'
-
Идеальный баланс для поддержания формы и достижения спортивных результатов. Начните свой путь к здоровью уже сегодня!
-
-
-
-
-
-
- Цена за день:
- 1000 ₽
+
+
+
+
+
Welcome, !
+
+
+
+
+
Our Plans
+
+
+
+
Basic Plan
+
$9.99/month
+
Get a personalized weekly meal plan.
+
-
- Итоговая стоимость:
- 5000 ₽
+
+
Premium Plan
+
$19.99/month
+
Weekly meal plan + personal nutritionist chat.
+
-
-
-
-
+
+
+
+
Your Orders
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jules-scratch/verification/verification.png b/jules-scratch/verification/verification.png
new file mode 100644
index 0000000..ea2b161
Binary files /dev/null and b/jules-scratch/verification/verification.png differ
diff --git a/jules-scratch/verification/verify_nutriplan.py b/jules-scratch/verification/verify_nutriplan.py
new file mode 100644
index 0000000..d858671
--- /dev/null
+++ b/jules-scratch/verification/verify_nutriplan.py
@@ -0,0 +1,19 @@
+from playwright.sync_api import sync_playwright, Page, expect
+
+def run(playwright):
+ browser = playwright.chromium.launch(headless=True)
+ page = browser.new_page()
+
+ # Navigate to the local server
+ page.goto("http://localhost:8000")
+
+ # Wait for the main heading to be visible to ensure the page is loaded
+ expect(page.get_by_role("heading", name="NutriPlan")).to_be_visible()
+
+ # Take a screenshot
+ page.screenshot(path="jules-scratch/verification/verification.png")
+
+ browser.close()
+
+with sync_playwright() as playwright:
+ run(playwright)
\ No newline at end of file
diff --git a/script.js b/script.js
index 80d0561..c782f00 100644
--- a/script.js
+++ b/script.js
@@ -1,61 +1,191 @@
-document.addEventListener('DOMContentLoaded', () => {
- const form = document.getElementById('nutriplan-form');
- if (!form) return;
-
- const pricePerDayEl = document.getElementById('price-per-day');
- const totalPriceEl = document.getElementById('total-price');
-
- // --- CONFIGURATION ---
- const BASE_PRICE_PER_DAY = 1000;
-
- const calculateAndDisplayPrice = () => {
- // --- GATHER DATA ---
- const formData = new FormData(form);
-
- const caloriesValue = form.querySelector('input[name="calories"]:checked').value;
- const calorieModifier = parseInt(form.querySelector('input[name="calories"]:checked').dataset.modifier, 10);
-
- const mealsValue = form.querySelector('input[name="meals"]:checked').value;
- const mealsModifier = parseInt(form.querySelector('input[name="meals"]:checked').dataset.modifier, 10);
-
- const durationInDays = parseInt(form.querySelector('input[name="duration"]:checked').value, 10);
-
- let totalExtras = 0;
- const extraOptions = [];
- form.querySelectorAll('input[name="extras"]:checked').forEach(el => {
- totalExtras += parseInt(el.dataset.modifier, 10);
- extraOptions.push(el.value);
- });
-
- // --- CALCULATE PRICE ---
- const pricePerDay = BASE_PRICE_PER_DAY + calorieModifier + mealsModifier;
- const totalPrice = (pricePerDay * durationInDays) + totalExtras;
-
- // --- DISPLAY PRICE ---
- pricePerDayEl.textContent = `${pricePerDay} ₽`;
- totalPriceEl.textContent = `${totalPrice} ₽`;
-
- return {
- calories: caloriesValue,
- meals: mealsValue,
- duration: durationInDays,
- extras: extraOptions,
- pricePerDay: pricePerDay,
- totalPrice: totalPrice
- };
- };
-
- // --- EVENT LISTENERS ---
- form.addEventListener('change', calculateAndDisplayPrice);
-
- form.addEventListener('submit', (e) => {
- e.preventDefault();
- const finalSelection = calculateAndDisplayPrice();
- console.log("--- NutriPlan Order ---");
- console.log(JSON.stringify(finalSelection, null, 2));
- alert('Заказ оформлен! Проверьте детали в консоли разработчика.');
+// -----------------------------------------------------------------------------
+// Configuration
+// -----------------------------------------------------------------------------
+// IMPORTANT: Replace these with your actual Supabase and Stripe keys.
+// These are placeholders and will not work.
+// You can get your keys from the Supabase and Stripe dashboards.
+
+const SUPABASE_URL = 'YOUR_SUPABASE_URL'; // e.g., 'https://your-project-id.supabase.co'
+const SUPABASE_ANON_KEY = 'YOUR_SUPABASE_ANON_KEY'; // The public "anon" key
+const STRIPE_PUBLISHABLE_KEY = 'YOUR_STRIPE_PUBLISHABLE_KEY'; // The public "pk_test_..." key
+
+// -----------------------------------------------------------------------------
+// Initialize Clients
+// -----------------------------------------------------------------------------
+// Check if the placeholder keys have been replaced. If not, show an alert.
+if (SUPABASE_URL === 'YOUR_SUPABASE_URL' || SUPABASE_ANON_KEY === 'YOUR_SUPABASE_ANON_KEY' || STRIPE_PUBLISHABLE_KEY === 'YOUR_STRIPE_PUBLISHABLE_KEY') {
+ alert('Please replace the placeholder API keys in script.js with your actual Supabase and Stripe keys.');
+}
+
+// Initialize the Supabase client
+const supabase = supabase.createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
+
+// Initialize the Stripe client
+const stripe = Stripe(STRIPE_PUBLISHABLE_KEY);
+
+// -----------------------------------------------------------------------------
+// DOM Element References
+// -----------------------------------------------------------------------------
+const authContainer = document.getElementById('auth-container');
+const userInfoSection = document.getElementById('user-info');
+const userEmailElement = document.getElementById('user-email');
+const logoutButton = document.getElementById('logout-button');
+const productsSection = document.getElementById('products');
+const ordersSection = document.getElementById('orders');
+const orderList = document.getElementById('order-list');
+const checkoutButtons = document.querySelectorAll('.checkout-button');
+
+// -----------------------------------------------------------------------------
+// Authentication Handling (Supabase)
+// -----------------------------------------------------------------------------
+
+// Function to set up the Supabase Auth UI
+const setupAuthUI = () => {
+ // This is a simplified example. For a real app, you might use Supabase's pre-built UI components
+ // or create your own form to call supabase.auth.signInWithPassword() or signUp().
+ // For this example, we'll simulate a login/logout flow.
+ authContainer.innerHTML = `
+
Login to see your orders and purchase plans.
+
+
+ `;
+ // Dummy login for demonstration
+ document.getElementById('login-button-dummy').addEventListener('click', () => {
+ // In a real app, you'd get email/password from a form
+ // const { user, error } = await supabase.auth.signInWithPassword({ email, password });
+ alert("This is a dummy login. In a real app, you would integrate Supabase's authentication UI or build your own login form.");
});
+};
+
+// Function to update the UI based on the user's auth state
+const updateUI = async (user) => {
+ if (user) {
+ // User is logged in
+ authContainer.classList.add('hidden');
+ userInfoSection.classList.remove('hidden');
+ ordersSection.classList.remove('hidden');
+ productsSection.style.display = 'block'; // Show products
+
+ userEmailElement.textContent = user.email;
+ await fetchOrders(user.id);
+ } else {
+ // User is logged out
+ authContainer.classList.remove('hidden');
+ userInfoSection.classList.add('hidden');
+ ordersSection.classList.add('hidden');
+ productsSection.style.display = 'block'; // Still show products
+
+ userEmailElement.textContent = '';
+ orderList.innerHTML = '
Login to see your past orders.
';
+ }
+};
+
+// Listen for authentication state changes
+supabase.auth.onAuthStateChange((event, session) => {
+ const user = session?.user || null;
+ updateUI(user);
+});
+
+// Handle logout
+logoutButton.addEventListener('click', async () => {
+ const { error } = await supabase.auth.signOut();
+ if (error) {
+ console.error('Error logging out:', error);
+ }
+});
+
+// -----------------------------------------------------------------------------
+// Stripe Checkout Integration
+// -----------------------------------------------------------------------------
+
+// Add event listeners to all "Choose Plan" buttons
+checkoutButtons.forEach(button => {
+ button.addEventListener('click', async (event) => {
+ const user = supabase.auth.user();
+ if (!user) {
+ alert('Please log in before making a purchase.');
+ return;
+ }
+
+ const productId = event.target.closest('.product-card').dataset.productId;
+
+ // This is where you would call a serverless function (e.g., a Supabase Edge Function)
+ // to create a Stripe Checkout session.
+ // The client should NOT create the session directly for security reasons.
+ // The function would take the product ID and user ID.
+
+ // --- Example of calling a Supabase Function ---
+ // const { data, error } = await supabase.functions.invoke('create-checkout-session', {
+ // body: { productId: productId }
+ // });
+ // if (error) {
+ // console.error('Error creating checkout session:', error);
+ // alert('Could not create checkout session.');
+ // return;
+ // }
+ // const { sessionId } = data;
+ // ---------------------------------------------
+
+ // For this example, we'll simulate the redirect to Stripe Checkout.
+ console.log(`Redirecting to Stripe Checkout for product: ${productId}`);
+ alert(`This is a demo. In a real application, you would be redirected to Stripe to purchase product ID: ${productId}. This requires a backend (like a Supabase Function) to securely create the session.`);
+
+ // --- This is the code you'd use with a real session ID ---
+ // const { error: stripeError } = await stripe.redirectToCheckout({
+ // sessionId: sessionId
+ // });
+ // if (stripeError) {
+ // console.error('Stripe redirect error:', stripeError);
+ // }
+ // ---------------------------------------------------------
+ });
+});
+
+
+// -----------------------------------------------------------------------------
+// Order Management (Supabase Database)
+// -----------------------------------------------------------------------------
+
+// Fetches and displays orders for the logged-in user
+const fetchOrders = async (userId) => {
+ // Assumes you have a table named 'orders' with columns like 'id', 'user_id', 'product_name', 'created_at'
+ const { data: orders, error } = await supabase
+ .from('orders')
+ .select('*')
+ .eq('user_id', userId)
+ .order('created_at', { ascending: false });
+
+ if (error) {
+ console.error('Error fetching orders:', error);
+ orderList.innerHTML = '