Skip to content

Commit

Permalink
Runtime server url setting (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
haiphucnguyen authored Dec 27, 2024
1 parent fc95c50 commit 32b9e7a
Show file tree
Hide file tree
Showing 39 changed files with 407 additions and 364 deletions.
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Dockerfile
.dockerignore
.idea
assets
node_modules
npm-debug.log
README.md
.next
.git
2 changes: 1 addition & 1 deletion .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ jobs:
- run: pnpm install
- name: Build the application
env:
NEXT_PUBLIC_BACKEND_API: "http://localhost:8080"
BACK_END_URL: "http://localhost:8080"
run: pnpm build
8 changes: 3 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ RUN apk add --no-cache libc6-compat
WORKDIR /app

# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
COPY package.json pnpm-lock.yaml* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
if [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Pnpm lockfile not found." && exit 1; \
fi


Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# FlowInquiry Client

[![Build status](https://github.com/flowinquiry/flowinquiry-frontend/actions/workflows/node.js.yml/badge.svg)](https://github.com/flowinquiry/flowinquiry-frontend/actions/workflows/node.js.yml)
![License](https://img.shields.io/badge/License-AGPLv3-blue)

## What is FlowInquiry

Expand All @@ -11,16 +12,16 @@ FlowInquiry is a service designed to streamline the management of cases, tickets
FlowInquiry addresses several challenges faced by organizations in managing cases, tickets, and team communication. Here are some specific use cases:

**On-Call System Management**
In an on-call system, teams often face challenges in managing incoming requests or incidents, particularly when multiple shifts or team members are involved. FlowInquiry ensures that each request follows a well-defined workflow, with SLAs for escalation and resolution. This helps reduce response times, avoids missed escalations, and provides clear accountability for handling incidents.
Managing incoming requests or incidents in an on-call system can be challenging with multiple shifts and team members. FlowInquiry streamlines the process by enforcing well-defined workflows with SLAs for escalation and resolution, reducing response times, avoiding missed escalations, and ensuring accountability.

**Case Management in CRM Applications**
CRM applications often struggle to manage customer cases effectively, especially when handling inquiries, complaints, or service requests. FlowInquiry enables teams to define custom workflows tailored to specific case types, such as refunds, escalations, or product inquiries. SLAs for each workflow stage ensure customers receive timely updates and resolutions, enhancing customer satisfaction and loyalty.
FlowInquiry helps CRM teams manage customer cases like inquiries, complaints, and service requests by enabling custom workflows tailored to case types such as refunds or escalations. SLAs at each workflow stage ensure timely updates and resolutions, boosting customer satisfaction and loyalty.

**Team Communication and Collaboration**
Effective communication within and across teams can be difficult in large organizations, especially when requests involve multiple departments or external stakeholders. FlowInquiry acts as a centralized platform where requests are logged, tracked, and routed through clearly defined workflows. This reduces miscommunication, prevents delays, and ensures all parties are aligned on priorities.
FlowInquiry enhances communication across teams by providing a centralized platform to log, track, and route requests through clear workflows. This minimizes miscommunication, prevents delays, and aligns all stakeholders on priorities, even in large organizations.

**Service Request Tracking for IT Teams**
IT teams managing internal service requests often encounter bottlenecks due to unclear processes or manual tracking. FlowInquiry allows IT departments to automate workflows for common requests such as software installation, access management, or issue resolution. The system ensures each request is assigned, processed, and resolved within agreed SLAs.
FlowInquiry automates IT service request workflows, such as software installation and access management, reducing bottlenecks caused by manual tracking. It ensures requests are assigned, processed, and resolved efficiently within SLA timelines.

By tailoring workflows to these and other scenarios, FlowInquiry empowers teams to streamline operations, meet deadlines, and deliver exceptional service to both internal and external stakeholders.

Expand Down Expand Up @@ -109,10 +110,10 @@ Set up the application environment variables by running the following script:
scripts/init_environments.sh
```

This script generates environment variables, including NEXT_PUBLIC_BACKEND_API, to establish the communication between the client and server. Example
This script generates environment variables, including BACK_END_URL, to establish the communication between the client and server. Example

```
NEXT_PUBLIC_API_BASE_URL=http://localhost:8080
BACK_END_URL=http://localhost:8080
```

We recommend running the `scripts/all.sh` script, as it streamlines the process by checking your environment settings and performing all necessary configurations, removing the need to execute multiple scripts manually.
Expand Down
2 changes: 1 addition & 1 deletion next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const nextConfig = {
fallback: [
{
source: "/api/:path*",
destination: `${process.env.NEXT_PUBLIC_BACKEND_API}/api/:path*`,
destination: `${process.env.BACK_END_URL}/api/:path*`,
},
],
};
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"nanoid": "^5.0.9",
"next": "^15.1.2",
"next-auth": "5.0.0-beta.25",
"next-runtime-env": "^3.2.2",
"next-themes": "^0.4.4",
"nuqs": "^2.2.3",
"react": "^19.0.0",
Expand Down
17 changes: 17 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion scripts/init_environments.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ while true; do
done

# Append to the .env.local file
echo "NEXT_PUBLIC_BACKEND_API=\"$backend_server\"" >> "$output_file"
echo "NEXT_PUBLIC_BACK_END_URL=\"$backend_server\"" >> "$output_file"


# Run npx auth and append its output to .env
Expand Down
2 changes: 1 addition & 1 deletion src/app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import LoginForm from "@/components/auth/login-form";

const LoginPage = () => {
const LoginPage = async () => {
return <LoginForm />;
};
export default LoginPage;
11 changes: 4 additions & 7 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import "./theme.css";

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { PublicEnvScript } from "next-runtime-env";

import { Toaster } from "@/components/ui/toaster";
import { TooltipProvider } from "@/components/ui/tooltip";
Expand All @@ -17,18 +18,14 @@ export const metadata: Metadata = {
description: "FlowInquiry dashboard",
};

const RootLayout = async ({
children,
}: Readonly<{
children: React.ReactNode;
}>) => {
const RootLayout = async ({ children }: { children: React.ReactNode }) => {
return (
<html suppressHydrationWarning={true} lang="en">
<head>
<PublicEnvScript />
<title>FlowInquiry - Ticket Management</title>
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
{/* Favicon for modern browsers */}
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
{/* Fallback favicon for older browsers */}
<link rel="icon" type="image/png" sizes="32x32" href="/favicon.png" />
</head>
<body className={inter.className}>
Expand Down
16 changes: 5 additions & 11 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import { redirect } from "next/navigation";
import { Home } from "@/components/home";

import { auth } from "@/auth";
const Page = async () => {
return <Home />;
};

export default async function Home() {
const session = await auth();
if (!session) {
console.warn("No authentication. Redirect to the login page ...");
redirect("/login");
} else {
redirect("/portal");
}
}
export default Page;
17 changes: 15 additions & 2 deletions src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import NextAuth, { User } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";

import apiAuthSignIn from "@/lib/auth";
import { BASE_URL } from "@/lib/constants";

export const { handlers, auth } = NextAuth({
providers: [
Expand All @@ -18,12 +19,24 @@ export const { handlers, auth } = NextAuth({
if (!credentials) {
throw new Error("Invalid credentials");
}
const user = await apiAuthSignIn(credentials);
return user;
return await apiAuthSignIn(credentials);
},
}),
],
callbacks: {
async redirect({ url, baseUrl }) {
// Allows relative callback URLs
if (url.startsWith("/")) return `${baseUrl}${url}`;
// Works for the deployment model while API_URL is the front url of the reverse proxy
else if (
process.env.NODE_ENV === "production" &&
new URL(url).origin === BASE_URL
)
return url;
// Allows callback URLs on the same origin
else if (new URL(url).origin === baseUrl) return url;
return baseUrl;
},
jwt({ token, account, user }) {
if (user) {
token.accessToken = user?.accessToken;
Expand Down
2 changes: 2 additions & 0 deletions src/components/admin-panel/content-layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"use client";

import { Navbar } from "@/components/admin-panel/navbar";

interface ContentLayoutProps {
Expand Down
27 changes: 22 additions & 5 deletions src/components/admin-panel/user-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { BASE_URL } from "@/lib/constants";

export function UserNav() {
const { data: session } = useSession();
Expand All @@ -49,7 +50,7 @@ export function UserNav() {
<AvatarImage
src={
session?.user?.imageUrl
? `/api/files/${session?.user?.imageUrl}`
? `${BASE_URL}/api/files/${session?.user?.imageUrl}`
: undefined
}
alt="Avatar"
Expand Down Expand Up @@ -101,7 +102,7 @@ export function UserNav() {
<DropdownMenuSeparator />
<DropdownMenuItem
className="hover:cursor-pointer"
onClick={() => signOut()}
onClick={() => signOut({ redirectTo: BASE_URL, redirect: true })}
>
<LogOut className="w-4 h-4 mr-3 text-muted-foreground" />
Sign out
Expand All @@ -110,12 +111,10 @@ export function UserNav() {
</DropdownMenu>
<DialogContent>
<DialogHeader className="flex items-center space-x-4">
{/* Logo */}
<div>
<AppLogo />
<AppLogo size={100} />
</div>

{/* Title and Description */}
<div>
<DialogTitle className="text-2xl font-bold">
FlowInquiry
Expand All @@ -128,6 +127,24 @@ export function UserNav() {
</DialogDescription>
</div>
</DialogHeader>

{/* Footer */}
<div className="mt-2 flex justify-between items-center border-t pt-2">
{/* Copyright and Year */}
<div className="text-sm text-gray-500 dark:text-gray-400">
© {new Date().getFullYear()} FlowInquiry. All rights reserved.
</div>

{/* Website Link */}
<a
href="https://www.flowinquiry.io"
target="_blank"
rel="noopener noreferrer"
className="text-sm font-medium text-blue-600 hover:underline dark:text-blue-400"
>
flowinquiry.io
</a>
</div>
</DialogContent>
</Dialog>
);
Expand Down
61 changes: 31 additions & 30 deletions src/components/app-logo.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
import React from "react";

type IconProps = React.HTMLAttributes<SVGElement>;
type IconProps = React.HTMLAttributes<SVGElement> & {
size?: number;
};

const AppLogo = (props: IconProps) => {
const AppLogo = ({ size = 40, ...props }: IconProps) => {
return (
<>
<svg
width="40"
height="40"
viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg"
>
<path
transform="scale(1.00287,1.00287)"
d="M30 100c-16.569 0-30-13.431-30-30v-40c0-16.569 13.431-30 30-30h40c16.569 0 30 13.431 30 30v40c0 16.569-13.431 30-30 30z"
fill="#000000"
stroke="none"
strokeWidth="1"
/>
<path
d="M49.942 52.994L90.595 51.529C88.068 47.352 87.436 43.698 82.606 43.068 75.377 42.128 68.148 41.185 60.918 40.242L18.843 34.762C20.101 36.792 39.724 53.361 49.942 52.994"
fill="#ffffff"
/>
<path
d="M0 9.786C4.391 17.043 26.615 32.858 32.953 33.672 50.283 35.903 67.61 38.132 84.939 40.36 81.546 34.753 80.759 31.01 74.627 29.401L47.91 22.378C31.94 18.182 15.97 13.984 0 9.786"
fill="#ffffff"
/>
<path
d="M63.108 66.207L94.349 59.547C92.321 56.201 92.315 54.188 88.522 54.358 82.364 54.631 76.208 54.907 70.051 55.18 58.708 55.686 47.365 56.194 36.023 56.698 37.298 58.064 54.94 67.947 63.108 66.207"
fill="#ffffff"
/>
</svg>
</>
<svg
width={size}
height={size}
viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
transform="scale(1.00287,1.00287)"
d="M30 100c-16.569 0-30-13.431-30-30v-40c0-16.569 13.431-30 30-30h40c16.569 0 30 13.431 30 30v40c0 16.569-13.431 30-30-30z"
fill="#000000"
stroke="none"
strokeWidth="1"
/>
<path
d="M49.942 52.994L90.595 51.529C88.068 47.352 87.436 43.698 82.606 43.068 75.377 42.128 68.148 41.185 60.918 40.242L18.843 34.762C20.101 36.792 39.724 53.361 49.942 52.994"
fill="#ffffff"
/>
<path
d="M0 9.786C4.391 17.043 26.615 32.858 32.953 33.672 50.283 35.903 67.61 38.132 84.939 40.36 81.546 34.753 80.759 31.01 74.627 29.401L47.91 22.378C31.94 18.182 15.97 13.984 0 9.786"
fill="#ffffff"
/>
<path
d="M63.108 66.207L94.349 59.547C92.321 56.201 92.315 54.188 88.522 54.358 82.364 54.631 76.208 54.907 70.051 55.18 58.708 55.686 47.365 56.194 36.023 56.698 37.298 58.064 54.94 67.947 63.108 66.207"
fill="#ffffff"
/>
</svg>
);
};

Expand Down
Loading

0 comments on commit 32b9e7a

Please sign in to comment.