rebuild: complete redesign — enterprise coaching ops platform
- Full redesign for Agile/DT/Enterprise coach personas - Light McKinsey-style UI: white + navy accent, Inter font - Marcus: Team Portfolio (14 teams, filters, sparklines, maturity) - Marcus: Team Detail (maturity bar, session log, action tracker) - Marcus: Session Capture (tagging toolbar, AI coaching questions, AI summary) - Priya: Workshop List + Live Capture (Decision/Tension/Question tags) - Priya: Workshop Summary (AI-generated, grouped by capture type) - David: Portfolio Reports + CEO Report Generator (Gemini-powered) - AI Assistant: 5 modes (Questions/Prep/Workshop/Summary/CEO Report) - Playbooks: Agile/DT/Facilitation library with filters - Persona switcher: Marcus / Priya / David - Netlify function: /api/gemini (server-side API proxy) - netlify.toml: functions dir + API route redirect
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
export default async (req, context) => {
|
||||
if (req.method === 'OPTIONS') {
|
||||
return new Response(null, {
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const { prompt, context: ctx, systemPrompt } = await req.json();
|
||||
const apiKey = process.env.GEMINI_API_KEY || 'AIzaSyDZn7tv1D3n2zuns8uaXIqp_z1FZTeVyKI';
|
||||
|
||||
const system = systemPrompt || 'You are an expert agile and enterprise coaching assistant for Falah Consulting. Be concise, practical, and outcome-focused.';
|
||||
const fullPrompt = ctx ? `Context: ${ctx}\n\n${prompt}` : prompt;
|
||||
|
||||
const geminiRes = await fetch(
|
||||
`https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${apiKey}`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
systemInstruction: { parts: [{ text: system }] },
|
||||
contents: [{ role: 'user', parts: [{ text: fullPrompt }] }],
|
||||
generationConfig: { temperature: 0.7, maxOutputTokens: 1024 },
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
if (!geminiRes.ok) {
|
||||
const err = await geminiRes.json();
|
||||
throw new Error(err?.error?.message || `Gemini HTTP ${geminiRes.status}`);
|
||||
}
|
||||
|
||||
const data = await geminiRes.json();
|
||||
const text = data?.candidates?.[0]?.content?.parts?.[0]?.text ?? '';
|
||||
|
||||
return new Response(JSON.stringify({ text }), {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
return new Response(JSON.stringify({ error: err.message }), {
|
||||
status: 500,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const config = { path: '/api/gemini' };
|
||||
Reference in New Issue
Block a user