Skip to content

Commit 4c1d1e5

Browse files
authored
Merge branch 'main' into first-review
2 parents 18a7104 + b6f1531 commit 4c1d1e5

31 files changed

Lines changed: 5221 additions & 0 deletions
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Copyright (c) 2026 Oracle and/or its affiliates.
2+
3+
The Universal Permissive License (UPL), Version 1.0
4+
5+
Subject to the condition set forth below, permission is hereby granted to any
6+
person obtaining a copy of this software, associated documentation and/or data
7+
(collectively the "Software"), free of charge and under any and all copyright
8+
rights in the Software, and any and all patent rights owned or freely
9+
licensable by each licensor hereunder covering either (i) the unmodified
10+
Software as contributed to or provided by such licensor, or (ii) the Larger
11+
Works (as defined below), to deal in both
12+
13+
(a) the Software, and
14+
(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
15+
one is included with the Software (each a "Larger Work" to which the Software
16+
is contributed by such licensors),
17+
18+
without restriction, including without limitation the rights to copy, create
19+
derivative works of, display, perform, and distribute the Software and make,
20+
use, sell, offer for sale, import, export, have made, and have sold the
21+
Software and the Larger Work(s), and to sublicense the foregoing rights on
22+
either these or other terms.
23+
24+
This license is subject to the following condition:
25+
The above copyright notice and either this complete permission notice or at
26+
a minimum a reference to the UPL must be included in all copies or
27+
substantial portions of the Software.
28+
29+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35+
SOFTWARE.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Recognition Card Generator
2+
3+
Internal demo application: generates branded employee recognition cards (background via image API, typography and layout composed in software), plus a web UI to upload employee CSV data, generate previews, download PNGs, and compose email drafts.
4+
5+
All application source and assets live in **`files/`**. This README stays at the repository root so the repo is easy to browse on GitHub.
6+
7+
---
8+
9+
## Repository layout
10+
11+
| Path | Purpose |
12+
|------|--------|
13+
| `files/src/` | FastAPI backend (`react_api.py`, image client) |
14+
| `files/frontend/` | React (Vite + TypeScript) web UI |
15+
| `files/data/` | Sample CSV files for testing |
16+
| `files/requirements.txt` | Python dependencies |
17+
| `files/output/` | Generated PNGs (created at runtime, **not** committed) |
18+
19+
---
20+
21+
## Prerequisites
22+
23+
- **Python 3.10+** (3.11+ recommended)
24+
- **Node.js 20+** and npm
25+
- API credentials for your image provider (set via environment variables; see `files/src/grok_openai_image.py` and `files/src/react_api.py`)
26+
27+
---
28+
29+
## Quick start (local)
30+
31+
### 1. Backend
32+
33+
```bash
34+
cd files
35+
python -m venv .venv
36+
.venv\Scripts\activate
37+
pip install -r requirements.txt
38+
```
39+
40+
Configure environment (at minimum, the variables your `ENDPOINT` / OpenAI-compatible image API expects), then:
41+
42+
```bash
43+
python -m uvicorn src.react_api:app --host 127.0.0.1 --port 8055 --reload
44+
```
45+
46+
### 2. Frontend
47+
48+
In a second terminal:
49+
50+
```bash
51+
cd files/frontend
52+
npm install
53+
npm run dev
54+
```
55+
56+
Open the URL Vite prints (usually `http://localhost:5173/`). The dev server proxies `/api/*` to `http://127.0.0.1:8055`.
57+
58+
### 3. Optional: company logo assets
59+
60+
Place official wordmarks in `files/frontend/public/` as `oracle-logo-red.png` and `oracle-logo-white.png` for exact on-card branding. Employee photos go under `files/frontend/public/employee-photos/`.
61+
62+
---
63+
64+
## CSV format
65+
66+
Use a header row. Important columns include `full_name`, `manager_name`, `manager_position`, `photo_asset_id` (path under `employee-photos/`), and **`employee_email`** (or `email` / `work_email`) for the email button. See `files/data/sample_employees_hr_use_cases.csv`.
67+
68+
---
69+
70+
## If you see a stray `frontend` folder at the repository root
71+
72+
The real app is under `files/frontend/`. A near-empty `frontend` at the top level can appear if a dev server held files open during a move. **Stop** any running `npm run dev` / Vite process, then delete the root `frontend` folder. Use only `files/frontend/` for the UI.
73+
74+
---
75+
76+
## Production notes
77+
78+
- Do **not** commit `files/output/`, `.env`, or `node_modules/`.
79+
- Tune API keys and base URLs via environment variables appropriate for your company’s deployment.
80+
- For enterprise email delivery with attachments, consider a server-side mail integration instead of relying on `mailto:` alone.
81+
82+
---
83+
84+
## License / confidentiality
85+
86+
Use and distribution are subject to your employer’s policies. Do not commit secrets or production credentials.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copy to `files/.env` and fill in. Never commit real secrets.
2+
# Image API (see files/src/grok_openai_image.py)
3+
4+
ENDPOINT=
5+
OPENAI_API_KEY=
6+
# Optional depending on provider:
7+
# OCI_PROJECT_ID=
8+
# COMPARTMENT_ID=
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
employee_id,first_name,full_name,employee_email,role,department,region,latest_win,recognition_category,manager_name,tone,language,photo_asset_id,output_channel
2+
E12345,Sara,Sara Al-Farsi,sara.alfarsi@example.com,Senior HR Analyst,HR,Middle East,Led onboarding improvements for 500 new hires,Operational Excellence,Omar Hassan,"warm, professional, celebratory",English,/employee-photos/sara-alfarsi.png,email
3+
E12346,David,David Clarke,david.clarke@example.com,Engineering Manager,Engineering,EMEA,Completed first 90 days with strong team impact,Team Integration,Emma Wright,"warm, professional, celebratory",English,/employee-photos/david-clarke.png,intranet
4+
E12347,Ana,Ana Rodrigues,ana.rodrigues@example.com,People Partner,HR,Americas,Launched mentorship circles across 4 offices,Employee Experience,Maria Torres,"warm, professional, celebratory",English,/employee-photos/ana-rodrigues.png,email
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import js from '@eslint/js'
2+
import globals from 'globals'
3+
import reactHooks from 'eslint-plugin-react-hooks'
4+
import reactRefresh from 'eslint-plugin-react-refresh'
5+
import tseslint from 'typescript-eslint'
6+
import { defineConfig, globalIgnores } from 'eslint/config'
7+
8+
export default defineConfig([
9+
globalIgnores(['dist']),
10+
{
11+
files: ['**/*.{ts,tsx}'],
12+
extends: [
13+
js.configs.recommended,
14+
tseslint.configs.recommended,
15+
reactHooks.configs.flat.recommended,
16+
reactRefresh.configs.vite,
17+
],
18+
languageOptions: {
19+
globals: globals.browser,
20+
},
21+
},
22+
])
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<meta name="theme-color" content="#f5f0e5" />
8+
<meta
9+
name="description"
10+
content="Generate employee recognition cards from CSV data in one click."
11+
/>
12+
<title>Recognition Card Studio</title>
13+
</head>
14+
<body>
15+
<div id="root"></div>
16+
<script type="module" src="/src/main.tsx"></script>
17+
</body>
18+
</html>

0 commit comments

Comments
 (0)