diff --git a/.github/workflows/main_mvapp.yml b/.github/workflows/main_mvapp.yml new file mode 100644 index 000000000..9fa51addb --- /dev/null +++ b/.github/workflows/main_mvapp.yml @@ -0,0 +1,73 @@ +name: Build and deploy Python app to Azure Web App - mvapp + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python version + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Create and start virtual environment + run: | + python -m venv venv + source venv/bin/activate + + - name: Install dependencies + run: | + source venv/bin/activate + pip install -r requirements.txt + + # Optional: Add step to run tests here (PyTest, Django test suites, etc.) + + - name: Zip artifact for deployment + run: zip -r release.zip . -x "venv/*" + + - name: Upload artifact for deployment jobs + uses: actions/upload-artifact@v4 + with: + name: python-app + path: | + release.zip + + deploy: + runs-on: ubuntu-latest + needs: build + environment: + name: 'Production' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + permissions: + id-token: write + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@v4 + with: + name: python-app + + - name: Unzip artifact for deployment + run: unzip release.zip + + - name: Login to Azure + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_06E5C5435BC7414FB166FB23024F3C82 }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_F872316154384EC089D46A6C30966422 }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_A8661C914A404B19B853D3847956A86C }} + + - name: 'Deploy to Azure Web App' + uses: azure/webapps-deploy@v3 + id: deploy-to-webapp + with: + app-name: 'mvapp' + slot-name: 'Production' diff --git a/src/app/(authenticated)/api/generate-msdoc/route.ts b/src/app/(authenticated)/api/generate-msdoc/route.ts new file mode 100644 index 000000000..39662fbbc --- /dev/null +++ b/src/app/(authenticated)/api/generate-msdoc/route.ts @@ -0,0 +1,63 @@ +import { NextRequest, NextResponse } from "next/server"; +import { Client } from "@microsoft/microsoft-graph-client"; +import { ConfidentialClientApplication } from "@azure/msal-node"; +import { Document, Packer, Paragraph, TextRun } from "docx"; +import "isomorphic-fetch"; + +export async function POST(req: NextRequest) { + const { filename, content } = await req.json(); + + if (!filename || !content) { + return NextResponse.json({ error: "Missing filename or content" }, { status: 400 }); + } + + try { + const msalConfig = { + auth: { + clientId: process.env.MS_GRAPH_CLIENT_ID!, + authority: `https://login.microsoftonline.com/${process.env.MS_GRAPH_TENANT_ID}`, + clientSecret: process.env.MS_GRAPH_CLIENT_SECRET!, + }, + }; + + const cca = new ConfidentialClientApplication(msalConfig); + const tokenResponse = await cca.acquireTokenByClientCredential({ + scopes: ["https://graph.microsoft.com/.default"], + }); + + const accessToken = tokenResponse?.accessToken; + if (!accessToken) { + return NextResponse.json({ error: "Failed to acquire token" }, { status: 401 }); + } + + // Create Word document + const doc = new Document({ + sections: [ + { + children: [ + new Paragraph({ children: [new TextRun({ text: filename, bold: true, size: 28 })] }), + new Paragraph({ children: [new TextRun(content)] }), + ], + }, + ], + }); + + const buffer = await Packer.toBuffer(doc); + + const graphClient = Client.init({ + authProvider: (done) => done(null, accessToken), + }); + + const uploadResponse = await graphClient + .api(`/me/drive/root:/${filename}.docx:/content`) + .put(buffer); + + return NextResponse.json({ + message: "File created in OneDrive", + fileUrl: uploadResponse.webUrl, + }); + } catch (err: any) { + console.error(err); + return NextResponse.json({ error: err.message }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/Favicon.ico b/src/app/Favicon.ico new file mode 100644 index 000000000..b7e834eb7 Binary files /dev/null and b/src/app/Favicon.ico differ diff --git a/src/app/favicon.ico b/src/app/favicon.ico deleted file mode 100644 index d0f9c71c5..000000000 Binary files a/src/app/favicon.ico and /dev/null differ diff --git a/src/app/globals.css b/src/app/globals.css index 55a3fa377..e89f5f958 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -10,7 +10,7 @@ --card-foreground: 222.2 84% 4.9%; --popover: 0 0% 100%; --popover-foreground: 222.2 84% 4.9%; - --primary: 136 80% 29%; + --primary: 206.04, 43.8%, 23.73%; --primary-foreground: 210 40% 98%; --secondary: 210 40% 96.1%; --secondary-foreground: 222.2 47.4% 11.2%; @@ -18,7 +18,7 @@ --muted-foreground: 215.4 16.3% 46.9%; --accent: 210 40% 96.1%; --accent-foreground: 222.2 47.4% 11.2%; - --destructive: 0 84.2% 60.2%; + --destructive: 40.7 99.2% 48.4%; --destructive-foreground: 210 40% 98%; --border: 214.3 31.8% 91.4%; --input: 214.3 31.8% 91.4%; @@ -33,7 +33,7 @@ --card-foreground: 210 40% 98%; --popover: 222.2 84% 4.9%; --popover-foreground: 210 40% 98%; - --primary: 136 80% 42%; + --primary: 206.04, 43.8%, 76.27%; --primary-foreground: 222.2 47.4% 11.2%; --secondary: 217.2 32.6% 17.5%; --secondary-foreground: 210 40% 98%; @@ -41,12 +41,12 @@ --muted-foreground: 215 20.2% 65.1%; --accent: 217.2 32.6% 17.5%; --accent-foreground: 210 40% 98%; - --destructive: 0 62.8% 30.6%; + --destructive: 40.7 99.2% 51.6%; --destructive-foreground: 210 40% 98%; --border: 217.2 32.6% 17.5%; --input: 217.2 32.6% 17.5%; --ring: 212.7 26.8% 83.9; - } + } } @layer base { diff --git a/src/features/theme/theme-config.ts b/src/features/theme/theme-config.ts index 57391f556..8124e5a22 100644 --- a/src/features/theme/theme-config.ts +++ b/src/features/theme/theme-config.ts @@ -1,5 +1,5 @@ -export const AI_NAME = "Azure Chat"; -export const AI_DESCRIPTION = "Azure Chat is a friendly AI assistant."; +export const AI_NAME = "Dayta Lab AI"; +export const AI_DESCRIPTION = "Experience secure, private AI solutions designed to transform data into valuable insights for your business. At Dayta Lab, your data privacy is our priority—analyze, generate, and manage insights with confidence on our trusted platform."; export const CHAT_DEFAULT_PERSONA = AI_NAME + " default"; export const CHAT_DEFAULT_SYSTEM_PROMPT = `You are a friendly ${AI_NAME} AI assistant. You must always return in markdown format. diff --git a/src/features/ui/button.tsx b/src/features/ui/button.tsx index ec86c6191..a4cd563ab 100644 --- a/src/features/ui/button.tsx +++ b/src/features/ui/button.tsx @@ -8,9 +8,9 @@ const buttonVariants = cva( { variants: { variant: { - default: "bg-primary text-primary-foreground hover:bg-primary/90", + default: "bg-primary text-primary-foreground hover:bg-destructive/90", destructive: - "bg-destructive text-destructive-foreground hover:bg-destructive/90", + "bg-destructive text-destructive-foreground hover:bg-destructive/90)", outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground", secondary: diff --git a/src/features/ui/hero.tsx b/src/features/ui/hero.tsx index c76895721..cd55f4d7b 100644 --- a/src/features/ui/hero.tsx +++ b/src/features/ui/hero.tsx @@ -8,13 +8,13 @@ interface HeroProps extends PropsWithChildren { export const Hero: FC = (props) => { return ( -
-
+
+

{props.title}

-

{props.description}

+

{props.description}

{props.children}
diff --git a/src/public/ai-icon11.png b/src/public/ai-icon11.png new file mode 100644 index 000000000..b7e834eb7 Binary files /dev/null and b/src/public/ai-icon11.png differ