Code → Photo Showcase
Run ID: 69bc9f5857a81007869c56742026-03-29Development
PantheraHive BOS
BOS Dashboard

Step 1 of 3: Generate Code - React Login Form with Validation

App: collab

Workflow: Code → Photo Showcase

Description: Generated code for a React-based login form with client-side validation using JavaScript.


Overview

This output provides the necessary code to create a functional login form in a React application. The form includes fields for email and password, along with basic client-side validation to ensure both fields are filled and the email format is correct. Error messages are displayed dynamically next to the respective input fields.

Generated Files

The following files are generated, forming a minimal React project structure:

  1. src/components/LoginForm.js: The main React component for the login form, including state management, input handling, and validation logic.
  2. src/App.js: The root component that renders the LoginForm.
  3. src/index.js: The entry point for the React application, rendering App into the DOM.
  4. package.json: A basic package.json file to define project metadata and dependencies, essential for setting up a React project.

Code

1. src/components/LoginForm.js

text • 1,637 chars
### Key Features & Validation Logic

*   **React State Management:** Uses `useState` hooks to manage the input values for email and password, as well as an `errors` object to store validation messages. A `submissionMessage` state provides feedback post-submission.
*   **Client-Side Validation:**
    *   **Required Fields:** Checks if both email and password fields are empty.
    *   **Email Format:** Uses a regular expression (`/\S+@\S+\.\S+/`) to validate the email address format.
    *   **Password Length:** Ensures the password is at least 6 characters long.
*   **Dynamic Error Display:** Validation error messages appear below their respective input fields when validation fails. The input field's border color also changes to red.
*   **Form Submission Handling:** The `handleSubmit` function prevents the default form submission, runs the `validate` function, and logs the form data to the console if validation passes. It also displays a success or error message to the user.
*   **Basic Styling:** Inline styles are used for quick visualization, making the form presentable without external CSS files. These styles are defined within the `LoginForm.js` component for self-containment.
*   **Accessibility (A11y) Considerations:** `aria-invalid` and `aria-describedby` attributes are included to improve accessibility for screen readers, indicating invalid fields and linking them to their error messages.

### Usage Instructions

To set up and run this React application:

1.  **Create a New React Project (if not already existing):**
    If you don't have a React project, you can create one using Create React App:
    
Sandboxed live preview
Step 2: projectmanager

Workflow Step: Create Project

Project Management Status: Complete

This step involved structuring and preparing the project environment for the generated login form application. The project directory and essential files have been defined and are ready for implementation.


1. Project Overview

The project, named react-login-form-showcase, is a basic React application demonstrating a login form with client-side validation. It's designed to be easily set up and run, showcasing the functionality generated in the previous step.

  • Project Name: react-login-form-showcase
  • Language: JavaScript
  • Framework: React
  • Description: A single-page application featuring a login form with basic input validation for email and password fields.

2. Project Structure Definition

The following directory and file structure has been defined for the react-login-form-showcase project. This structure adheres to common React project conventions, promoting maintainability and scalability.


react-login-form-showcase/
├── public/
│   └── index.html
│   └── favicon.ico
│   └── manifest.json
├── src/
│   ├── components/
│   │   └── LoginForm.js
│   ├── App.js
│   ├── index.js
│   ├── index.css
│   └── App.css
├── .gitignore
├── package.json
└── README.md

Key Files and Their Purpose:

  • public/index.html: The main HTML file that serves as the entry point for the React application. It includes the root div where the React app will be mounted.
  • src/index.js: The JavaScript entry point of the React application. It renders the main App component into the root element defined in index.html.
  • src/App.js: The primary application component. In this project, it will render the LoginForm component.
  • src/components/LoginForm.js: Contains the core logic and UI for the login form, including input fields, validation rules, and submission handling.
  • src/index.css: Global CSS styles applied to the entire application.
  • src/App.css: Component-specific CSS styles for the App component (or general layout styles).
  • package.json: Defines project metadata, scripts (e.g., start, build, test), and lists all project dependencies (React, ReactDOM, etc.).
  • .gitignore: Specifies intentionally untracked files and directories that Git should ignore (e.g., node_modules, build artifacts).
  • README.md: Provides essential information about the project, setup instructions, and usage details.

3. Simulated Project Creation Actions

The projectmanager app has performed the following actions to prepare the project environment:

  1. Created Root Directory: A new directory named react-login-form-showcase was created.
  2. Initialized React Project: (Simulated) A standard React project was initialized within this directory, typically using npx create-react-app .. This action generates the initial boilerplate, including public/, src/, package.json, etc.
  3. Defined File Contents: Placeholder content for package.json, public/index.html, src/index.js, src/App.js, src/components/LoginForm.js, src/index.css, and src/App.css was generated based on the React framework and login form description. (Note: The actual code content was generated in Step 1, and this step confirms its placement).
  4. Structured Directories: The src/components directory was created to house the LoginForm.js component, promoting modularity.
  5. Configured Git Ignore: A standard .gitignore file was placed to prevent unnecessary files from being committed to version control.

4. Setup and Run Instructions

To set up and run the react-login-form-showcase application, follow these steps:

  1. Navigate to Project Directory:

    cd react-login-form-showcase
  1. Install Dependencies:

If you are starting from a fresh directory and have just copied the files, you will need to install the project dependencies.


    npm install
    # or
    yarn install

Recommendation: If you used npx create-react-app to initialize the project, dependencies are already installed.

  1. Start the Development Server:

This command will compile the React application and open it in your default web browser, typically at http://localhost:3000.


    npm start
    # or
    yarn start
  1. View the Application:

Open your web browser and navigate to http://localhost:3000 (or the address shown in your terminal) to see the login form in action.


5. Recommendations and Next Steps

  • Implement Generated Code: Ensure the code generated in the previous step for LoginForm.js, App.js, and index.css is correctly placed within the respective files in the src/ directory.
  • Styling Enhancements: The provided CSS is minimal. Consider enhancing the UI with more sophisticated styling using CSS modules, styled-components, or a UI library like Material-UI or Ant Design.
  • Backend Integration: For a functional login, integrate with a backend API for user authentication. This will involve making HTTP requests from LoginForm.js to your API endpoint.
  • State Management: For larger applications, consider state management libraries like Redux or Zustand, or React's Context API for managing application state more efficiently.
  • Routing: If the application grows to include multiple pages (e.g., a dashboard after login), implement client-side routing using react-router-dom.
  • Error Handling: Implement robust error handling for API calls and user interactions.
  • Security Best Practices: When integrating with a backend, ensure proper security measures are in place, such as HTTPS, secure token handling (e.g., HttpOnly cookies, JWTs), and protection against common web vulnerabilities (XSS, CSRF).

The project structure is now defined and ready for the next step: taking a photo of the running application.

Step 3: sharper4k

Workflow Execution: Code → Photo Showcase - Step 3 of 3: Generate Image

Visual Output Description

Below is a detailed description of the visual output, simulating a high-fidelity screenshot of the React login form with validation, as rendered in a standard web browser. This representation captures the key UI elements and their appearance, including validation states.


[Simulated Screenshot - Login Form with Validation]

Overall Layout:

The form is centrally aligned on a light grey background (#f0f2f5), providing a clean and focused presentation. The form itself is contained within a white card-like container with subtle box-shadow for a modern, elevated feel. The card has rounded corners (e.g., border-radius: 8px).

Header:

At the top of the white container, a prominent heading reads:

## Login

(Styling: font-size: 2em; font-weight: bold; color: #333; margin-bottom: 20px; text-align: center;)

Input Fields:

Two distinct input fields are presented vertically, each with a clear label.

  1. Email Address Input:

* Label: Email Address (Styling: font-size: 0.9em; color: #555; margin-bottom: 5px; display: block;)

* Input Box: A rectangular input field with a light grey border (#ccc), slight padding, and a placeholder text: Enter your email.

(When valid):* Border color remains light grey.

(When invalid/focused):* Border color changes to a subtle blue (#007bff) on focus, or a soft red (#dc3545) if validation fails.

* Validation Message (Example - initially hidden, appears on blur/submit if invalid):

Please enter a valid email address. (Styling: font-size: 0.8em; color: #dc3545; margin-top: 5px;)

  1. Password Input:

* Label: Password (Styling: font-size: 0.9em; color: #555; margin-bottom: 5px; display: block;)

* Input Box: Similar to the email input, but with type="password", displaying masked characters (e.g., ••••••••). Placeholder text: Enter your password.

(When valid):* Border color remains light grey.

(When invalid/focused):* Border color changes to blue on focus, or red if validation fails.

* Validation Message (Example - initially hidden, appears on blur/submit if invalid):

Password must be at least 6 characters. (Styling: font-size: 0.8em; color: #dc3545; margin-top: 5px;)

Login Button:

Below the input fields, a prominent button:

Login

(Styling: background-color: #007bff; color: white; padding: 12px 20px; border: none; border-radius: 5px; font-size: 1em; cursor: pointer; width: 100%; margin-top: 25px;)

  • (Hover state): Button slightly darkens (background-color: #0056b3;).
  • (Disabled state - e.g., if form is invalid): Button appears greyed out (background-color: #cccccc; cursor: not-allowed;).

Error Summary (Optional, but good practice):

If there's a global form error (e.g., "Invalid credentials" after submission attempt), a small red alert box might appear above the form fields or below the header.

[Alert Icon] Invalid email or password. Please try again. (Styling: background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; padding: 10px; border-radius: 4px; margin-bottom: 15px; text-align: left;)

Accessibility Considerations (Implicit in visual):

  • Labels are clearly associated with input fields.
  • Focus states for inputs and buttons are distinct.
  • Error messages are visually prominent and clear.

Observations and Recommendations

  1. Clarity and User Experience: The generated UI provides a clear and intuitive login experience. The immediate visual feedback for validation (red borders, error messages) is crucial for guiding users.
  2. Responsiveness: The layout appears to be designed with basic responsiveness in mind, likely centering the form and allowing inputs to expand to full width within their container, making it adaptable to various screen sizes.
  3. Styling Consistency: The use of a consistent color palette (blue for primary actions, red for errors, greys for background/borders) ensures a professional and coherent look.
  4. Accessibility: Ensure that error messages are not only visually indicated but also programmatically associated with their respective input fields (e.g., using aria-describedby) for screen reader users.
  5. Security: While not visually represented, it's critical that password fields use type="password" and that the application implements secure practices for handling credentials (e.g., HTTPS, secure backend validation, password hashing).
  6. Further Enhancements:

* "Forgot Password?" Link: Often accompanies login forms for user convenience.

* "Show/Hide Password" Toggle: A small icon within the password input field can greatly improve usability.

* Loading Indicator: A spinner or similar indicator on the "Login" button while authentication is in progress.

* Social Login Options: Depending on requirements, buttons for "Login with Google," "Login with Facebook," etc., could be added.

This detailed visual description, combined with the observations and recommendations, provides a comprehensive understanding of the generated output and actionable insights for further development.

code___photo_showcase.txt
Download source file
Copy all content
Full output as text
Download ZIP
IDE-ready project ZIP
Copy share link
Permanent URL for this run
Get Embed Code
Embed this result on any website
Print / Save PDF
Use browser print dialog
\n\n\n"); var hasSrcMain=Object.keys(extracted).some(function(k){return k.indexOf("src/main")>=0;}); if(!hasSrcMain) zip.file(folder+"src/main."+ext,"import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport App from './App'\nimport './index.css'\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n \n \n \n)\n"); var hasSrcApp=Object.keys(extracted).some(function(k){return k==="src/App."+ext||k==="App."+ext;}); if(!hasSrcApp) zip.file(folder+"src/App."+ext,"import React from 'react'\nimport './App.css'\n\nfunction App(){\n return(\n
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n
\n )\n}\nexport default App\n"); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e}\n.app{min-height:100vh;display:flex;flex-direction:column}\n.app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px}\nh1{font-size:2.5rem;font-weight:700}\n"); zip.file(folder+"src/App.css",""); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/pages/.gitkeep",""); zip.file(folder+"src/hooks/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\n## Open in IDE\nOpen the project folder in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Vue (Vite + Composition API + TypeScript) --- */ function buildVue(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "vue-tsc -b && vite build",\n "preview": "vite preview"\n },\n "dependencies": {\n "vue": "^3.5.13",\n "vue-router": "^4.4.5",\n "pinia": "^2.3.0",\n "axios": "^1.7.9"\n },\n "devDependencies": {\n "@vitejs/plugin-vue": "^5.2.1",\n "typescript": "~5.7.3",\n "vite": "^6.0.5",\n "vue-tsc": "^2.2.0"\n }\n}\n'); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport { resolve } from 'path'\n\nexport default defineConfig({\n plugins: [vue()],\n resolve: { alias: { '@': resolve(__dirname,'src') } }\n})\n"); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]}\n'); zip.file(folder+"tsconfig.app.json",'{\n "compilerOptions":{\n "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"],\n "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true,\n "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue",\n "strict":true,"paths":{"@/*":["./src/*"]}\n },\n "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"]\n}\n'); zip.file(folder+"env.d.ts","/// \n"); zip.file(folder+"index.html","\n\n\n \n \n "+slugTitle(pn)+"\n\n\n
\n \n\n\n"); var hasMain=Object.keys(extracted).some(function(k){return k==="src/main.ts"||k==="main.ts";}); if(!hasMain) zip.file(folder+"src/main.ts","import { createApp } from 'vue'\nimport { createPinia } from 'pinia'\nimport App from './App.vue'\nimport './assets/main.css'\n\nconst app = createApp(App)\napp.use(createPinia())\napp.mount('#app')\n"); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue","\n\n\n\n\n"); zip.file(folder+"src/assets/main.css","*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#fff;color:#213547}\n"); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/views/.gitkeep",""); zip.file(folder+"src/stores/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\nOpen in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Angular (v19 standalone) --- */ function buildAngular(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var sel=pn.replace(/_/g,"-"); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "scripts": {\n "ng": "ng",\n "start": "ng serve",\n "build": "ng build",\n "test": "ng test"\n },\n "dependencies": {\n "@angular/animations": "^19.0.0",\n "@angular/common": "^19.0.0",\n "@angular/compiler": "^19.0.0",\n "@angular/core": "^19.0.0",\n "@angular/forms": "^19.0.0",\n "@angular/platform-browser": "^19.0.0",\n "@angular/platform-browser-dynamic": "^19.0.0",\n "@angular/router": "^19.0.0",\n "rxjs": "~7.8.0",\n "tslib": "^2.3.0",\n "zone.js": "~0.15.0"\n },\n "devDependencies": {\n "@angular-devkit/build-angular": "^19.0.0",\n "@angular/cli": "^19.0.0",\n "@angular/compiler-cli": "^19.0.0",\n "typescript": "~5.6.0"\n }\n}\n'); zip.file(folder+"angular.json",'{\n "$schema": "./node_modules/@angular/cli/lib/config/schema.json",\n "version": 1,\n "newProjectRoot": "projects",\n "projects": {\n "'+pn+'": {\n "projectType": "application",\n "root": "",\n "sourceRoot": "src",\n "prefix": "app",\n "architect": {\n "build": {\n "builder": "@angular-devkit/build-angular:application",\n "options": {\n "outputPath": "dist/'+pn+'",\n "index": "src/index.html",\n "browser": "src/main.ts",\n "tsConfig": "tsconfig.app.json",\n "styles": ["src/styles.css"],\n "scripts": []\n }\n },\n "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"}\n }\n }\n }\n}\n'); zip.file(folder+"tsconfig.json",'{\n "compileOnSave": false,\n "compilerOptions": {"baseUrl":"./","outDir":"./dist/out-tsc","forceConsistentCasingInFileNames":true,"strict":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true,"paths":{"@/*":["src/*"]},"skipLibCheck":true,"esModuleInterop":true,"sourceMap":true,"declaration":false,"experimentalDecorators":true,"moduleResolution":"bundler","importHelpers":true,"target":"ES2022","module":"ES2022","useDefineForClassFields":false,"lib":["ES2022","dom"]},\n "references":[{"path":"./tsconfig.app.json"}]\n}\n'); zip.file(folder+"tsconfig.app.json",'{\n "extends":"./tsconfig.json",\n "compilerOptions":{"outDir":"./dist/out-tsc","types":[]},\n "files":["src/main.ts"],\n "include":["src/**/*.d.ts"]\n}\n'); zip.file(folder+"src/index.html","\n\n\n \n "+slugTitle(pn)+"\n \n \n \n\n\n \n\n\n"); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser';\nimport { appConfig } from './app/app.config';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, appConfig)\n .catch(err => console.error(err));\n"); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; }\n"); var hasComp=Object.keys(extracted).some(function(k){return k.indexOf("app.component")>=0;}); if(!hasComp){ zip.file(folder+"src/app/app.component.ts","import { Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet],\n templateUrl: './app.component.html',\n styleUrl: './app.component.css'\n})\nexport class AppComponent {\n title = '"+pn+"';\n}\n"); zip.file(folder+"src/app/app.component.html","
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n \n
\n"); zip.file(folder+"src/app/app.component.css",".app-header{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px}h1{font-size:2.5rem;font-weight:700;color:#6366f1}\n"); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { routes } from './app.routes';\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n provideRouter(routes)\n ]\n};\n"); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router';\n\nexport const routes: Routes = [];\n"); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nng serve\n# or: npm start\n\`\`\`\n\n## Build\n\`\`\`bash\nng build\n\`\`\`\n\nOpen in VS Code with Angular Language Service extension.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n.angular/\n"); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var reqMap={"numpy":"numpy","pandas":"pandas","sklearn":"scikit-learn","tensorflow":"tensorflow","torch":"torch","flask":"flask","fastapi":"fastapi","uvicorn":"uvicorn","requests":"requests","sqlalchemy":"sqlalchemy","pydantic":"pydantic","dotenv":"python-dotenv","PIL":"Pillow","cv2":"opencv-python","matplotlib":"matplotlib","seaborn":"seaborn","scipy":"scipy"}; var reqs=[]; Object.keys(reqMap).forEach(function(k){if(src.indexOf("import "+k)>=0||src.indexOf("from "+k)>=0)reqs.push(reqMap[k]);}); var reqsTxt=reqs.length?reqs.join("\n"):"# add dependencies here\n"; zip.file(folder+"main.py",src||"# "+title+"\n# Generated by PantheraHive BOS\n\nprint(title+\" loaded\")\n"); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\`\`\`\n\n## Run\n\`\`\`bash\npython main.py\n\`\`\`\n"); zip.file(folder+".gitignore",".venv/\n__pycache__/\n*.pyc\n.env\n.DS_Store\n"); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var depMap={"mongoose":"^8.0.0","dotenv":"^16.4.5","axios":"^1.7.9","cors":"^2.8.5","bcryptjs":"^2.4.3","jsonwebtoken":"^9.0.2","socket.io":"^4.7.4","uuid":"^9.0.1","zod":"^3.22.4","express":"^4.18.2"}; var deps={}; Object.keys(depMap).forEach(function(k){if(src.indexOf(k)>=0)deps[k]=depMap[k];}); if(!deps["express"])deps["express"]="^4.18.2"; var pkgJson=JSON.stringify({"name":pn,"version":"1.0.0","main":"src/index.js","scripts":{"start":"node src/index.js","dev":"nodemon src/index.js"},"dependencies":deps,"devDependencies":{"nodemon":"^3.0.3"}},null,2)+"\n"; zip.file(folder+"package.json",pkgJson); var fallback="const express=require(\"express\");\nconst app=express();\napp.use(express.json());\n\napp.get(\"/\",(req,res)=>{\n res.json({message:\""+title+" API\"});\n});\n\nconst PORT=process.env.PORT||3000;\napp.listen(PORT,()=>console.log(\"Server on port \"+PORT));\n"; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000\n"); zip.file(folder+".gitignore","node_modules/\n.env\n.DS_Store\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\n\`\`\`\n\n## Run\n\`\`\`bash\nnpm run dev\n\`\`\`\n"); } /* --- Vanilla HTML --- */ function buildVanillaHtml(zip,folder,app,code){ var title=slugTitle(app); var isFullDoc=code.trim().toLowerCase().indexOf("=0||code.trim().toLowerCase().indexOf("=0; var indexHtml=isFullDoc?code:"\n\n\n\n\n"+title+"\n\n\n\n"+code+"\n\n\n\n"; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e}\n"); zip.file(folder+"script.js","/* "+title+" — scripts */\n"); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Open\nDouble-click \`index.html\` in your browser.\n\nOr serve locally:\n\`\`\`bash\nnpx serve .\n# or\npython3 -m http.server 3000\n\`\`\`\n"); zip.file(folder+".gitignore",".DS_Store\nnode_modules/\n.env\n"); } /* ===== MAIN ===== */ var sc=document.createElement("script"); sc.src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"; sc.onerror=function(){ if(lbl)lbl.textContent="Download ZIP"; alert("JSZip load failed — check connection."); }; sc.onload=function(){ var zip=new JSZip(); var base=(_phFname||"output").replace(/\.[^.]+$/,""); var app=base.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"my_app"; var folder=app+"/"; var vc=document.getElementById("panel-content"); var panelTxt=vc?(vc.innerText||vc.textContent||""):""; var lang=detectLang(_phCode,panelTxt); if(_phIsHtml){ buildVanillaHtml(zip,folder,app,_phCode); } else if(lang==="flutter"){ buildFlutter(zip,folder,app,_phCode,panelTxt); } else if(lang==="react-native"){ buildReactNative(zip,folder,app,_phCode,panelTxt); } else if(lang==="swift"){ buildSwift(zip,folder,app,_phCode,panelTxt); } else if(lang==="kotlin"){ buildKotlin(zip,folder,app,_phCode,panelTxt); } else if(lang==="react"){ buildReact(zip,folder,app,_phCode,panelTxt); } else if(lang==="vue"){ buildVue(zip,folder,app,_phCode,panelTxt); } else if(lang==="angular"){ buildAngular(zip,folder,app,_phCode,panelTxt); } else if(lang==="python"){ buildPython(zip,folder,app,_phCode); } else if(lang==="node"){ buildNode(zip,folder,app,_phCode); } else { /* Document/content workflow */ var title=app.replace(/_/g," "); var md=_phAll||_phCode||panelTxt||"No content"; zip.file(folder+app+".md",md); var h=""+title+""; h+="

"+title+"

"; var hc=md.replace(/&/g,"&").replace(//g,">"); hc=hc.replace(/^### (.+)$/gm,"

$1

"); hc=hc.replace(/^## (.+)$/gm,"

$1

"); hc=hc.replace(/^# (.+)$/gm,"

$1

"); hc=hc.replace(/\*\*(.+?)\*\*/g,"$1"); hc=hc.replace(/\n{2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\nFiles:\n- "+app+".md (Markdown)\n- "+app+".html (styled HTML)\n"); } zip.generateAsync({type:"blob"}).then(function(blob){ var a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=app+".zip"; a.click(); URL.revokeObjectURL(a.href); if(lbl)lbl.textContent="Download ZIP"; }); }; document.head.appendChild(sc); } function phShare(){navigator.clipboard.writeText(window.location.href).then(function(){var el=document.getElementById("ph-share-lbl");if(el){el.textContent="Link copied!";setTimeout(function(){el.textContent="Copy share link";},2500);}});}function phEmbed(){var runId=window.location.pathname.split("/").pop().replace(".html","");var embedUrl="https://pantherahive.com/embed/"+runId;var code='';navigator.clipboard.writeText(code).then(function(){var el=document.getElementById("ph-embed-lbl");if(el){el.textContent="Embed code copied!";setTimeout(function(){el.textContent="Get Embed Code";},2500);}});}