Skip to content

Commit cf05f1b

Browse files
Sma1lboyautofix-ci[bot]PengyuChen01pengyu
authored
chore(frontend): fix some fd UI styling (#136)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Enabled loading of remote images for a smoother media experience. - Introduced an animated, floating navigation bar alongside interactive components like a project showcase and an improved prompt form featuring a typewriter effect and file upload. - Added a new "About" page for additional information about the application. - Introduced a modal component for enhanced user interaction. - Expanded project management capabilities with new features for forking projects, updating visibility, and subscribing to projects. - Implemented a project status monitoring hook to enhance user experience. - Added enhanced error handling and user feedback mechanisms through toast notifications. - **Style** - Refreshed the UI with a cohesive indigo color theme, enhanced animations (blink and subtle pulse), and refined visuals for sign-in error displays and animated borders. - **Chores** - Updated routing for cleaner URLs and optimized dependency management for smoother performance. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: PengyuChen01 <121841974+PengyuChen01@users.noreply.github.com> Co-authored-by: pengyu <pengyuchen01@gmail.com>
1 parent 26fb8a1 commit cf05f1b

Some content is hidden

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

58 files changed

+3245
-1098
lines changed

backend/.env

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ PORT=8080
22
JWT_SECRET="JACKSONCHENNAHEULALLENPENGYU"
33
JWT_REFRESH_SECRET="JACKSONCHENNAHEULALLENPENGYUREFRESH"
44
SALT_ROUNDS=123
5+
NODE_ENV="DEV"

backend/src/app.module.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import { APP_INTERCEPTOR } from '@nestjs/core';
1616
import { LoggingInterceptor } from 'src/interceptor/LoggingInterceptor';
1717
import { PromptToolModule } from './prompt-tool/prompt-tool.module';
1818

19+
// TODO(Sma1lboy): move to a separate file
20+
function isProduction(): boolean {
21+
return process.env.NODE_ENV === 'production';
22+
}
1923
@Module({
2024
imports: [
2125
ConfigModule.forRoot({ isGlobal: true }),
@@ -33,7 +37,7 @@ import { PromptToolModule } from './prompt-tool/prompt-tool.module';
3337
TypeOrmModule.forRoot({
3438
type: 'sqlite',
3539
database: join(process.cwd(), './database.db'),
36-
synchronize: true,
40+
synchronize: !isProduction(),
3741
entities: [__dirname + '/**/*.model{.ts,.js}'],
3842
}),
3943
InitModule,

backend/src/chat/chat.model.ts

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Column,
66
ManyToOne,
77
JoinColumn,
8+
RelationId,
89
} from 'typeorm';
910
import { Message } from 'src/chat/message.model';
1011
import { SystemBaseModel } from 'src/system-base-model/system-base.model';
@@ -56,6 +57,11 @@ export class Chat extends SystemBaseModel {
5657
@Field(() => User)
5758
user: User;
5859

60+
// Adding relation id to easily access the user id
61+
@RelationId((chat: Chat) => chat.user)
62+
@Field(() => ID)
63+
userId: string;
64+
5965
@ManyToOne(() => Project, (project) => project.chats)
6066
@Field(() => Project, { nullable: true })
6167
project: Project;

backend/src/chat/chat.resolver.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,7 @@ export class ChatResolver {
7878
}
7979

8080
@Query(() => [String], { nullable: true })
81-
async getAvailableModelTags(
82-
@GetUserIdFromToken() userId: string,
83-
): Promise<string[]> {
84-
this.logger.log('Fetching model tags for user:', userId);
81+
async getAvailableModelTags(): Promise<string[]> {
8582
try {
8683
const response = await this.chatProxyService.fetchModelTags();
8784
this.logger.log('Loaded model tags:', response);

backend/src/common/model-provider/openai-model-provider.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export class OpenAIModelProvider implements IModelProvider {
3737

3838
for (const model of chatModels) {
3939
if (model.default) {
40-
this.defaultModel = model.model;
40+
this.defaultModel = model.alias || model.model;
4141
}
4242
if (!model.endpoint || !model.token) continue;
4343

@@ -95,7 +95,7 @@ export class OpenAIModelProvider implements IModelProvider {
9595
const completion = await queue.add(async () => {
9696
const result = await this.openai.chat.completions.create({
9797
messages: input.messages,
98-
model: input.model,
98+
model: input.model || this.baseModel,
9999
stream: false,
100100
});
101101
if (!result) throw new Error('No completion result received');
@@ -255,4 +255,8 @@ export class OpenAIModelProvider implements IModelProvider {
255255
// OpenAI SDK handles its own request management
256256
return [];
257257
}
258+
259+
get baseModel(): string {
260+
return this.defaultModel;
261+
}
258262
}

backend/src/project/build-system-utils.ts

+26-18
Original file line numberDiff line numberDiff line change
@@ -87,29 +87,37 @@ export function buildProjectSequenceByProject(
8787
* Generates a project name prompt based on the provided description.
8888
*/
8989
export function generateProjectNamePrompt(description: string): string {
90-
return `You are a project name generator. Based on the following project description, generate a concise, memorable, and meaningful project name.
90+
return `You are a project name generator specializing in creating clear, descriptive titles for technical projects. Based on the provided description, generate a concise yet comprehensive project title.
9191
9292
Input Description: ${description}
9393
94-
Requirements for the project name:
95-
1. Must be 1-3 words maximum
96-
2. Should be clear and professional
97-
3. Avoid generic terms like "project" or "system"
98-
4. Use camelCase or kebab-case format
99-
5. Should reflect the core functionality or purpose
100-
6. Must be unique and memorable
101-
7. Should be easy to pronounce
102-
8. Avoid acronyms unless they're very intuitive
94+
Project Title Guidelines:
95+
1. Create a descriptive title (not exceeding 20 words)
96+
2. Format as a standard phrase that clearly identifies the project purpose
97+
3. Include specific details about:
98+
- The type of application (e.g., Backend, Frontend, Mobile App)
99+
- The industry or organization it serves
100+
- Key functionality or purpose
101+
4. Ensure the title is:
102+
- Clear and descriptive
103+
- Professional and straightforward
104+
- Easy to understand for stakeholders
105+
- Specific enough to differentiate from other projects
106+
5. Acceptable formatting examples:
107+
- "Backend System for Financial Reporting"
108+
- "Mobile App for Patient Monitoring"
109+
- "Data Analytics Platform for Retail Inventory"
110+
6. Include organization names when relevant (e.g., "Backend App for Chinese Sakura Bank")
103111
104-
Please respond ONLY with the project name, without any explanation or additional text.
112+
Please respond ONLY with the project title. Do not include explanations or additional text.
105113
106-
Example inputs and outputs:
107-
Description: "A task management system with real-time collaboration features"
108-
Output: taskFlow
114+
Example high-quality outputs:
115+
Description: "A task management system with real-time collaboration features for marketing teams"
116+
Output: Collaboration Platform for Marketing Task Management
109117
110-
Description: "An AI-powered document analysis and extraction system"
111-
Output: docMind
118+
Description: "An AI-powered document analysis system for legal departments"
119+
Output: AI Document Analysis Tool for Legal Departments
112120
113-
Description: "A microservice-based e-commerce platform with advanced inventory management"
114-
Output: tradeCore`;
121+
Description: "A microservice-based e-commerce platform with advanced inventory management for a furniture retailer"
122+
Output: E-commerce System for Furniture Inventory Management`;
115123
}

backend/src/project/dto/project.input.ts

+59-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// DTOs for Project APIs
2-
import { InputType, Field, ID } from '@nestjs/graphql';
2+
import { InputType, Field, ID, ObjectType } from '@nestjs/graphql';
33
import { IsNotEmpty, IsString, IsUUID, IsOptional } from 'class-validator';
4+
import { Project } from '../project.model';
45

56
/**
67
* @deprecated We don't need project upsert
@@ -41,6 +42,12 @@ export class CreateProjectInput {
4142

4243
@Field(() => String, { nullable: true })
4344
databaseType?: string;
45+
46+
@Field(() => Boolean, { nullable: true })
47+
public: boolean;
48+
49+
@Field(() => String, { nullable: true, defaultValue: 'gpt-4o-mini' })
50+
model: string;
4451
}
4552

4653
@InputType()
@@ -60,3 +67,54 @@ export class IsValidProjectInput {
6067
@Field(() => String, { nullable: true })
6168
projectPath: string;
6269
}
70+
71+
@InputType()
72+
export class UpdateProjectPublicStatusInput {
73+
@Field(() => ID)
74+
projectId: string;
75+
76+
@Field()
77+
isPublic: boolean;
78+
}
79+
80+
@InputType()
81+
export class UpdateProjectPhotoUrlInput {
82+
@Field(() => ID)
83+
projectId: string;
84+
85+
@Field()
86+
photoUrl: string;
87+
}
88+
89+
@InputType()
90+
export class SubscribeToProjectInput {
91+
@Field(() => ID)
92+
projectId: string;
93+
}
94+
95+
@InputType()
96+
export class ForkProjectInput {
97+
@Field(() => ID)
98+
projectId: string;
99+
}
100+
101+
@ObjectType()
102+
export class ProjectSubscriptionResult {
103+
@Field()
104+
success: boolean;
105+
106+
@Field({ nullable: true })
107+
message?: string;
108+
109+
@Field(() => Project, { nullable: true })
110+
project?: Project;
111+
}
112+
113+
@InputType()
114+
export class FetchPublicProjectsInputs {
115+
@Field()
116+
strategy: 'trending' | 'latest';
117+
118+
@Field()
119+
size: number;
120+
}

backend/src/project/project.model.ts

+65-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,71 @@ export class Project extends SystemBaseModel {
6565
@OneToMany(() => Chat, (chat) => chat.project, {
6666
cascade: true, // Automatically save related chats
6767
lazy: true, // Load chats only when accessed
68-
onDelete: 'CASCADE', // Delete chats when user is deleted
68+
onDelete: 'CASCADE', // Delete chats when project is deleted
6969
})
7070
chats: Promise<Chat[]>;
71+
72+
/**
73+
* Represents whether the project is public or private
74+
*/
75+
@Field()
76+
@Column({ default: false })
77+
isPublic: boolean;
78+
79+
/**
80+
* Counts the number of times this project has been subscribed to (copied)
81+
*/
82+
@Field()
83+
@Column({ default: 0 })
84+
subNumber: number;
85+
86+
/**
87+
* The URL to the project's screenshot or thumbnail
88+
*/
89+
@Field({ nullable: true })
90+
@Column({ nullable: true })
91+
photoUrl: string;
92+
93+
/**
94+
* Unique identifier for tracking project lineage
95+
* Used to track which projects are copies of others
96+
*/
97+
@Field()
98+
@Column({ unique: true, default: () => 'uuid_generate_v4()' })
99+
uniqueProjectId: string;
100+
101+
/**
102+
* If this project is a copy/fork, stores the uniqueProjectId of the original project.
103+
* Projects with forkedFromId are fully editable by their new owner while maintaining
104+
* a reference to the original project they were copied from.
105+
*/
106+
@Field({ nullable: true })
107+
@Column({ nullable: true })
108+
forkedFromId: string;
109+
110+
/**
111+
* Reference to the original project if this is a copy/fork
112+
*/
113+
@Field(() => Project, { nullable: true })
114+
@ManyToOne(() => Project, (project) => project.forks, { nullable: true })
115+
@JoinColumn({ name: 'forkedFromId', referencedColumnName: 'uniqueProjectId' })
116+
forkedFrom: Project;
117+
118+
/**
119+
* Projects that were copied from this project
120+
*/
121+
@Field(() => [Project], { nullable: true })
122+
@OneToMany(() => Project, (project) => project.forkedFrom)
123+
forks: Project[];
124+
125+
/**
126+
* Projects copied from this one
127+
* Maintained for backwards compatibility, same as forks
128+
*/
129+
@Field(() => [Project], {
130+
nullable: true,
131+
description: 'Projects that are copies of this project',
132+
})
133+
@OneToMany(() => Project, (project) => project.forkedFrom)
134+
subscribers: Project[];
71135
}

0 commit comments

Comments
 (0)