Skip to content

Commit 1ce087f

Browse files
committed
Initial Commit 3
1 parent 6e28b1d commit 1ce087f

File tree

732 files changed

+103783
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

732 files changed

+103783
-0
lines changed

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
github: pdovhomilja
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: 🐞 Bug report
2+
description: Create a bug report to help us improve Ledger1CRM App
3+
title: "[BUG:]"
4+
labels: [👀 Exploration Pending, 🐞 bug]
5+
projects: ["pdovhomilja/1"]
6+
body:
7+
- type: markdown
8+
attributes:
9+
value: |
10+
Thanks for taking the time to fill out this bug report!
11+
- type: textarea
12+
attributes:
13+
label: Describe the bug
14+
description: A clear and concise description of what the bug is.
15+
validations:
16+
required: true
17+
- type: textarea
18+
attributes:
19+
label: Steps to reproduce
20+
description: Describe how to reproduce the behavior.
21+
placeholder: |
22+
1. Go to '...'
23+
2. Click on '...'
24+
3. Scroll down to '...'
25+
4. See error
26+
validations:
27+
required: true
28+
- type: dropdown
29+
attributes:
30+
multiple: true
31+
label: Browsers
32+
description: Select the browsers where the issue can be reproduced (that you know of).
33+
options:
34+
- "Chrome"
35+
- "Brave"
36+
- "Firefox"
37+
- "Safari"
38+
- "Edge"
39+
- "Opera"
40+
- "Other (add additional context)"
41+
- type: input
42+
id: context
43+
attributes:
44+
label: Additional context (Is this in dev or production?)
45+
description: Add any other context about the problem or helpful links here.

.github/workflows/azure-deply.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Build and deploy Node.js app to Azure Web App
2+
3+
on:
4+
push:
5+
branches:
6+
- main # Change this if your branch is named 'master'
7+
8+
env:
9+
AZURE_WEBAPP_NAME: 'your-app-service-name' # REPLACE with your specific Azure App Name
10+
NODE_VERSION: '20.x' # Ensure this matches your Azure Runtime Stack
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Set up Node.js version
20+
uses: actions/setup-node@v4
21+
with:
22+
node-version: ${{ env.NODE_VERSION }}
23+
cache: 'npm'
24+
25+
- name: npm install, build, and test
26+
run: |
27+
npm install
28+
npm run build --if-present
29+
npm run test --if-present
30+
31+
# Zips the build to prepare for deployment
32+
- name: Upload artifact for deployment job
33+
uses: actions/upload-artifact@v4
34+
with:
35+
name: node-app
36+
path: .
37+
38+
deploy:
39+
runs-on: ubuntu-latest
40+
needs: build
41+
environment:
42+
name: 'Production'
43+
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
44+
45+
steps:
46+
- name: Download artifact from build job
47+
uses: actions/download-artifact@v4
48+
with:
49+
name: node-app
50+
51+
- name: 'Deploy to Azure Web App'
52+
id: deploy-to-webapp
53+
uses: azure/webapps-deploy@v3
54+
with:
55+
app-name: ${{ env.AZURE_WEBAPP_NAME }}
56+
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
57+
package: .

.github/workflows/ci.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: CI Pipeline
2+
on: [push]
3+
jobs:
4+
cypress-run:
5+
runs-on: ubuntu-latest
6+
7+
steps:
8+
- name: Start MongoDB
9+
uses: supercharge/mongodb-github-action@1.10.0
10+
with:
11+
mongodb-version: 6.0
12+
mongodb-username: nextcrm
13+
mongodb-password: nextcrm
14+
mongodb-db: nextcrm
15+
16+
- name: Checkout
17+
uses: actions/checkout@v3
18+
19+
- name: Install Dependencies
20+
run: npm install -g pnpm && pnpm install --frozen-lockfile
21+
22+
- name: Run Unit Tests
23+
run: npx vitest run
24+
25+
- name: Run Lint
26+
run: npm run lint
27+
continue-on-error: true # Warning only for now
28+
29+
- name: Prisma Schema Validate
30+
uses: elijaholmos/prisma-schema-validate@v1.0.0
31+
env:
32+
DATABASE_URL: ${{ secrets.DATABASE_URL }}
33+
CMS_DATABASE_URL: ${{ secrets.CMS_DATABASE_URL }}
34+
ENCRYPTION_KEY: ${{ secrets.API_KEY_ENCRYPTION_KEY }}
35+
36+
- name: Prisma Generate and Push
37+
run: |
38+
npx prisma generate
39+
npx prisma db push
40+
npx prisma db seed
41+
env:
42+
DATABASE_URL: ${{ secrets.DATABASE_URL }}
43+
CMS_DATABASE_URL: ${{ secrets.CMS_DATABASE_URL }}
44+
ENCRYPTION_KEY: ${{ secrets.API_KEY_ENCRYPTION_KEY }}

.github/workflows/cms_cms.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
2+
# More GitHub Actions for Azure: https://github.com/Azure/actions
3+
4+
name: Build and deploy Node.js app to Azure Web App - cms
5+
6+
on:
7+
push:
8+
branches:
9+
- cms
10+
workflow_dispatch:
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read #This is required for actions/checkout
17+
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- name: Set up Node.js version
22+
uses: actions/setup-node@v3
23+
with:
24+
node-version: '24.x'
25+
26+
- name: npm install, build, and test
27+
run: |
28+
npm install
29+
npm run build --if-present
30+
npm run test --if-present
31+
32+
- name: Upload artifact for deployment job
33+
uses: actions/upload-artifact@v4
34+
with:
35+
name: node-app
36+
path: .
37+
38+
deploy:
39+
runs-on: ubuntu-latest
40+
needs: build
41+
42+
steps:
43+
- name: Download artifact from build job
44+
uses: actions/download-artifact@v4
45+
with:
46+
name: node-app
47+
48+
- name: 'Deploy to Azure Web App'
49+
id: deploy-to-webapp
50+
uses: azure/webapps-deploy@v3
51+
with:
52+
app-name: 'cms'
53+
slot-name: 'Production'
54+
package: .
55+
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_6CBFCF5F964D46BF9BBDEF30B4B76FE1 }}

.github/workflows/docker.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Publish Docker image
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
7+
jobs:
8+
push_to_registry:
9+
name: Push Docker image to Docker Hub
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Check out the repo
13+
uses: actions/checkout@v3
14+
15+
- name: Log in to Docker Hub
16+
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
17+
with:
18+
username: ${{ secrets.DOCKER_USERNAME }}
19+
password: ${{ secrets.DOCKER_PASSWORD }}
20+
21+
- name: Extract metadata (tags, labels) for Docker
22+
id: meta
23+
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
24+
with:
25+
images: nextcrmio/nextcrm-0.0.3-beta
26+
27+
- name: Use secrets
28+
run: |
29+
echo "" > .env.local # Clear the .env.local file
30+
echo DATABASE_URL: ${{ secrets.DATABASE_URL }} >> .env
31+
echo CMS_DATABASE_URL: ${{ secrets.CMS_DATABASE_URL }} >> .env
32+
echo GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} >> .env.local
33+
echo GOOGLE_ID: ${{ secrets.GOOGLE_ID }} >> .env.local
34+
echo GOOGLE_SECRET: ${{ secrets.GOOGLE_SECRET }} >> .env.local
35+
echo RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }} >> .env.local
36+
echo DO_ENDPOINT: ${{ secrets.DO_ENDPOINT }} >> .env.local
37+
echo DO_REGION: ${{ secrets.DO_REGION }} >> .env.local
38+
echo DO_ACCESS_KEY_ID: ${{ secrets.DO_ACCESS_KEY_ID }} >> .env.local
39+
echo DO_ACCESS_KEY_SECRET: ${{ secrets.DO_ACCESS_KEY_SECRET }} >> .env.local
40+
echo DATABASE_URL: ${{ secrets.DATABASE_URL }} >> .env.local
41+
echo CMS_DATABASE_URL: ${{ secrets.CMS_DATABASE_URL }} >> .env.local
42+
echo JWT_SECRET: ${{ secrets.JWT_SECRET }} >> .env.local
43+
echo NEXTAUTH_URL: ${{ secrets.NEXTAUTH_URL }} >> .env.local
44+
echo NEXT_PUBLIC_APP_NAME: ${{ secrets.NEXT_PUBLIC_APP_NAME }} >> .env.local
45+
echo NEXT_PUBLIC_APP_V: ${{ secrets.NEXT_PUBLIC_APP_V }} >> .env.local
46+
echo NEXT_PUBLIC_APP_URL: ${{ secrets.NEXT_PUBLIC_APP_URL }} >> .env.local
47+
48+
- name: Build and push Docker image
49+
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
50+
with:
51+
context: .
52+
push: true
53+
tags: ${{ steps.meta.outputs.tags }}
54+
labels: ${{ steps.meta.outputs.labels }}
55+
file: ./Dockerfile_actions # custom Dockerfile name for your github actions

actions/cms/ai-form-generator.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
"use server";
2+
3+
import { generateObject } from "ai";
4+
import { openai } from "@ai-sdk/openai";
5+
import { z } from "zod";
6+
import { getServerSession } from "next-auth";
7+
import { authOptions } from "@/lib/auth";
8+
9+
// Schema definition for the form fields
10+
// This matches the frontend FormField interface
11+
const FormFieldSchema = z.object({
12+
id: z.string().describe("Unique identifier for the field (e.g., 'first_name')"),
13+
type: z.enum([
14+
"text",
15+
"email",
16+
"tel",
17+
"url",
18+
"textarea",
19+
"select",
20+
"radio",
21+
"checkbox",
22+
"date",
23+
"file",
24+
]).describe("The input type of the field"),
25+
label: z.string().describe("Human-readable label for the field"),
26+
placeholder: z.string().optional().describe("Placeholder text for inputs"),
27+
required: z.boolean().default(false).describe("Whether the field is required"),
28+
options: z.array(z.string()).optional().describe("Options for select, radio, or checkbox types"),
29+
width: z.enum(["full", "half"]).default("full").describe("Visual width of the field container"),
30+
helpText: z.string().optional().describe("Helper text or tooltip for the field"),
31+
});
32+
33+
const FormGenerationSchema = z.object({
34+
title: z.string().describe("Suggested title for the form"),
35+
description: z.string().describe("Short description of what the form is for"),
36+
fields: z.array(FormFieldSchema).describe("List of fields to include in the form"),
37+
});
38+
39+
export async function generateFormFields(prompt: string) {
40+
try {
41+
const session = await getServerSession(authOptions);
42+
if (!session?.user) {
43+
throw new Error("Unauthorized");
44+
}
45+
46+
const { object } = await generateObject({
47+
model: openai("gpt-4o"),
48+
schema: FormGenerationSchema,
49+
prompt: `Create a professional form structure based on this request: "${prompt}".
50+
51+
Ensure the fields are logical, user-friendly, and cover all necessary information implied by the prompt.
52+
For 'select', 'radio', or 'checkbox' types, provide realistic and comprehensive options.
53+
Use 'half' width for related short fields (e.g., First Name + Last Name) to improve layout.
54+
55+
Return a JSON object with a title, description, and list of fields.`,
56+
});
57+
58+
return {
59+
success: true,
60+
data: object
61+
};
62+
63+
} catch (error) {
64+
console.error("AI Form Generation Error:", error);
65+
return {
66+
success: false,
67+
error: "Failed to generate form. Please try again."
68+
};
69+
}
70+
}

actions/cms/auth-actions.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"use server";
2+
3+
import { prismadb } from "@/lib/prisma";
4+
import { getServerSession } from "next-auth";
5+
import { authOptions } from "@/lib/auth";
6+
import { hash } from "bcryptjs";
7+
import { logActivityInternal } from "@/actions/audit";
8+
9+
export async function updatePassword(password: string) {
10+
try {
11+
const session = await getServerSession(authOptions);
12+
13+
if (!session?.user?.id) {
14+
return { success: false, error: "Unauthorized" };
15+
}
16+
17+
if (password.length < 6) {
18+
return { success: false, error: "Password must be at least 6 characters" };
19+
}
20+
21+
const hashedPassword = await hash(password, 12);
22+
23+
await prismadb.users.update({
24+
where: { id: session.user.id },
25+
data: {
26+
password: hashedPassword,
27+
forcePasswordReset: false
28+
}
29+
});
30+
31+
await logActivityInternal(
32+
session.user.id,
33+
"Changed Password",
34+
"Security",
35+
"User successfully changed their password"
36+
);
37+
38+
return { success: true };
39+
} catch (error: any) {
40+
console.error("Failed to update password", error);
41+
return { success: false, error: "Failed to update password" };
42+
}
43+
}

0 commit comments

Comments
 (0)