Skip to content

Commit

Permalink
Feature/landing page data (#87)
Browse files Browse the repository at this point in the history
* feat: landing page data

* feat: created clubLinks routes

* feat: added spotlight api

* feat: added questions api

* fix: typecheck
  • Loading branch information
ManasC478 authored Feb 26, 2025
1 parent 5d13b4a commit 7179f32
Show file tree
Hide file tree
Showing 7 changed files with 527 additions and 71 deletions.
92 changes: 59 additions & 33 deletions db-scripts/01_createdb.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'acm_website')\gexec

create extension if not exists pg_trgm;

create type events_enum as enum ('workshop', 'seminar', 'hackathon', 'conference', 'meetup', 'test', 'other');
create type cs_fields_enum as enum ('web development', 'machine learning', 'cloud computing', 'artificial intelligence', 'networking', 'cybersecurity', 'mobile development', 'game development', 'data science');
create type target_audience_enum as enum ('students');
create type equipment_condition_enum as enum ('ready', 'broken', 'in maintenance');
create type membership_term_enum as enum ('semester', 'annual');
create type education_level_enum as enum('undergraduate', 'graduate');
create type membership_request_status_enum as enum ('pending', 'approved', 'declined');
create type industry_enum as enum ('banking and finance', 'aerospace', 'healthcare', 'automotive', 'energy', 'technology');
create type officer_position_enum as enum ('president', 'vice president', 'dev team officer', 'treasurer', 'social media manager');
create type events_enum as enum ('Workshop', 'Seminar', 'Hackathon', 'Conference', 'Meetup', 'Tech Talk', 'Other');
create type cs_fields_enum as enum ('Web Development', 'Machine Learning', 'Cloud Computing', 'Artificial Intelligence', 'Networking', 'Cybersecurity', 'Mobile Development', 'Game Development', 'Data Science');
create type target_audience_enum as enum ('Students');
create type equipment_condition_enum as enum ('Ready', 'Broken', 'In Maintenance');
create type membership_term_enum as enum ('Semester', 'Annual');
create type education_level_enum as enum('Undergraduate', 'Graduate');
create type membership_request_status_enum as enum ('Pending', 'Approved', 'Declined');
create type industry_enum as enum ('Banking and Finance', 'Aerospace', 'Healthcare', 'Automotive', 'Energy', 'Technology');
create type officer_position_enum as enum ('President', 'Vice President', 'Dev Team Officer', 'Treasurer', 'Social Media Manager', 'Secretary');
create type user_role_enum as enum ('user', 'member', 'admin');
create type year_enum as enum ('freshman', 'sophomore', 'junior', 'senior', 'alumni');
create type project_status_enum as enum ('not started', 'looking for members', 'in progress', 'completed');
create type year_enum as enum ('Freshman', 'Sophomore', 'Junior', 'Senior', 'Alumni');
create type project_status_enum as enum ('Not Started', 'Looking for Members', 'In Progress', 'Completed');

create table if not exists majors(
name text not null,
Expand Down Expand Up @@ -86,7 +86,7 @@ create table if not exists equipment_rentals(
return_date date not null,
-- price money not null,
price numeric(10,2) not null,
condition equipment_condition_enum not null default 'ready',
condition equipment_condition_enum not null default 'Ready',
PRIMARY KEY(user_id, item_id),
FOREIGN KEY(item_id) REFERENCES equipment_item(id) on update cascade,
FOREIGN KEY(user_id) REFERENCES users(id) on update cascade on delete set null
Expand All @@ -101,13 +101,20 @@ create table if not exists blacklist(
);

create table if not exists urls(

id serial,
original_url text not null,
short_url text not null,
PRIMARY KEY(id)
);

create table if not exists files(
key text not null,
name text not null,
created_at timestamp not null default current_timestamp,
primary key(key)
);


create table if not exists events(
id serial,
created_at timestamp not null default current_timestamp,
Expand All @@ -127,22 +134,16 @@ create table if not exists events(
shortened_event_url integer,
member_only boolean not null default false,
PRIMARY KEY(id),
FOREIGN KEY(shortened_event_url) REFERENCES urls(id) on update cascade
);

create table if not exists files(
key text not null,
name text not null,
created_at timestamp not null default current_timestamp,
primary key(key)
FOREIGN KEY(shortened_event_url) REFERENCES urls(id) on update cascade,
foreign key(image) references files(key) on update cascade
);

create table if not exists events_files(
event_id integer not null,
file_key text not null,
primary key(event_id, file_key),
foreign key(event_id) references events(id) on update cascade on delete cascade,
foreign key(file_key) references files(key) on update cascade on delete cascade
foreign key(file_key) references files(key) on update cascade
);

create table if not exists bookmarked_events(
Expand Down Expand Up @@ -196,7 +197,7 @@ create table if not exists projects(
name text not null,
description text not null,
github_link text,
status project_status_enum not null default 'not started',
status project_status_enum not null default 'Not Started',
PRIMARY KEY(id)
);

Expand All @@ -205,7 +206,7 @@ create table if not exists projects_files(
file_key text not null,
primary key(project_id, file_key),
foreign key(project_id) references projects(id) on update cascade on delete cascade,
foreign key(file_key) references files(key) on update cascade on delete cascade
foreign key(file_key) references files(key) on update cascade
);

create table if not exists interested_in_projects(
Expand Down Expand Up @@ -233,6 +234,31 @@ create table if not exists sponsors(
primary key(name)
);

create table if not exists club_links(
id serial,
instagram text,
discord text,
linkedin text,
member_application text,
primary key(id)
);

create table if not exists landing_spotlights(
id serial,
event_id integer not null,
image_key text not null,
primary key(id),
foreign key(event_id) references events(id) on update cascade,
foreign key(image_key) references files(key) on update cascade
);

create table if not exists landing_questions(
id serial,
question text not null,
answer text not null,
primary key(id)
);

create index projects_name_trgm_idx on projects using gin (name gin_trgm_ops);
create index companies_name_trgm_idx on companies using gin (name gin_trgm_ops);
create index events_name_trgm_idx on events using gin (name gin_trgm_ops);
Expand Down Expand Up @@ -346,21 +372,21 @@ BEGIN

CASE
WHEN gradYear - currentYear = 0 THEN
RETURN 'senior';
RETURN 'Senior';
WHEN gradYear - currentYear = 1 THEN
IF level = 'graduate' THEN
RETURN 'sophomore';
IF level = 'Graduate' THEN
RETURN 'Sophomore';
END IF;
RETURN 'junior';
RETURN 'Junior';
WHEN gradYear - currentYear = 2 THEN
IF level = 'graduate' THEN
RETURN 'freshman';
IF level = 'Graduate' THEN
RETURN 'Freshman';
END IF;
RETURN 'sophomore';
RETURN 'Sophomore';
WHEN gradYear - currentYear = 3 THEN
RETURN 'freshman';
RETURN 'Freshman';
ELSE
RETURN 'alumni';
RETURN 'Alumni';
END CASE;
END;
$$;
Expand Down
60 changes: 38 additions & 22 deletions db-scripts/02_insert_data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -156,24 +156,28 @@ insert into majors(name) values
INSERT INTO users (
id, name, email, major, education_level, grad_date, interests, profile_pic, linkedin, github, website, role, paid
) VALUES
('user1', 'Alice Smith', '[email protected]', 'Aerospace Engineering, BS', 'undergraduate', '2025-05-15',
'{"web development", "machine learning"}', NULL, 'https://linkedin.com', 'https://github.com', NULL, 'user', NULL),
('user2', 'Bob Johnson', '[email protected]', 'Chemistry, BA', 'graduate', '2022-12-10',
'{"networking", "cybersecurity"}', NULL, 'https://linkedin.com', 'https://github.com', NULL, 'admin', NULL),
('user3', 'Charlie Brown', '[email protected]', 'History, BA', 'undergraduate', '2026-08-30',
'{"mobile development", "game development"}', NULL, 'https://www.linkedin.com', NULL, 'https://www.bing.com/', 'member', 'semester'),
('user4', 'Diana Evans', '[email protected]', 'Computer Science, BS', 'graduate', '2023-11-01',
'{"artificial intelligence"}', NULL, 'https://linkedin.com', 'https://github.com', NULL, 'user', NULL),
('user5', 'Evan Wright', '[email protected]', 'Philosophy, BA', 'undergraduate', '2025-04-20',
'{"data science", "cloud computing"}', NULL, NULL, 'https://github.com', 'https://www.google.com/', 'member', 'annual');
('user1', 'Alice Smith', '[email protected]', 'Aerospace Engineering, BS', 'Undergraduate', '2025-05-15',
'{"Web Development", "Machine Learning"}', NULL, 'https://linkedin.com', 'https://github.com', NULL, 'user', NULL),
('user2', 'Bob Johnson', '[email protected]', 'Chemistry, BA', 'Graduate', '2022-12-10',
'{"Networking", "Cybersecurity"}', NULL, 'https://linkedin.com', 'https://github.com', NULL, 'user', NULL),
('user3', 'Charlie Brown', '[email protected]', 'History, BA', 'Undergraduate', '2026-08-30',
'{"Mobile Development", "Game Development"}', NULL, 'https://www.linkedin.com', NULL, 'https://www.bing.com/', 'user', NULL),
('user4', 'Diana Evans', '[email protected]', 'Computer Science, BS', 'Graduate', '2023-11-01',
'{"Artificial Intelligence"}', NULL, 'https://linkedin.com', 'https://github.com', NULL, 'user', NULL),
('user5', 'Evan Wright', '[email protected]', 'Philosophy, BA', 'Undergraduate', '2025-04-20',
'{"Data Science", "Cloud Computing"}', NULL, NULL, 'https://github.com', 'https://www.google.com/', 'user', NULL);

insert into files(key, name) values
('default.png', 'Default Image');


-- Insert company 1
INSERT INTO companies (name, location, description, industry_id) values
('Tech Innovations', 'San Francisco, CA', 'Leading provider of AI-driven solutions', 'technology'),
('Eco Green Solutions', 'Austin, TX', 'Sustainable and renewable energy provider', 'energy'),
('Global Finance Corp', 'New York, NY', 'International financial services and investments', 'banking and finance'),
('Health Plus', 'Boston, MA', 'Healthcare technology and medical devices', 'healthcare'),
('Future Automotive', 'Detroit, MI', 'Next-generation automotive manufacturing', 'automotive');
INSERT INTO companies (name, location, description, industry_id, logo) values
('Tech Innovations', 'San Francisco, CA', 'Leading provider of AI-driven solutions', 'Technology', 'default.png'),
('Eco Green Solutions', 'Austin, TX', 'Sustainable and renewable energy provider', 'Energy', 'default.png'),
('Global Finance Corp', 'New York, NY', 'International financial services and investments', 'Banking and Finance', 'default.png'),
('Health Plus', 'Boston, MA', 'Healthcare technology and medical devices', 'Healthcare', 'default.png'),
('Future Automotive', 'Detroit, MI', 'Next-generation automotive manufacturing', 'Automotive', 'default.png');

INSERT INTO projects (name, description) values
('AI Chatbot', 'An intelligent chatbot using natural language processing'),
Expand All @@ -190,19 +194,19 @@ INSERT INTO events (
VALUES (
'Tech Conference 2024', 'San Francisco, CA', '2024-11-01', '2024-11-03',
'A three-day conference on the latest in technology and innovation.',
'conference', 500, '09:00', '17:00',
'{"artificial intelligence", "machine learning"}', 'students', 'event1.png', false
'Conference', 500, '09:00', '17:00',
'{"Artificial Intelligence", "Machine Learning"}', 'Students', 'default.png', false
),
('Hackathon 2024', 'New York, NY', '2024-12-10', '2024-12-12',
'A 48-hour hackathon focused on software development and innovation.',
'hackathon', 300, '08:00', '20:00',
'{"networking"}', 'students', 'event2.png', false
'Hackathon', 300, '08:00', '20:00',
'{"Networking"}', 'Students', 'default.png', false
),
(
'Data Science Workshop', 'Boston, MA', '2024-09-15', '2024-09-15',
'A one-day workshop on data science fundamentals and techniques.',
'workshop', 150, '10:00', '16:00',
'{"data science"}', 'students', 'event3.png', true
'Workshop', 150, '10:00', '16:00',
'{"Data Science"}', 'Students', 'default.png', true
);

INSERT INTO event_companies(event_id, company_id) VALUES
Expand Down Expand Up @@ -295,3 +299,15 @@ INSERT INTO sponsors VALUES
('Google', '/sponsors/google/logo'),
('Tesla', '/sponsors/tesla/logo'),
('FetchAI', '/sponsors/fetchai/logo');

INSERT INTO club_links(instagram, discord, linkedin, member_application) VALUES
('https://www.instagram.com/sjsuacm/', 'https://discord.gg/Rw85ngkExu', 'https://www.linkedin.com/company/sjsu-computer-science-club/about/', 'https://docs.google.com/forms/d/e/1FAIpQLSfNBu-IGm7bhUmMf2cSOmNca3SiJZyVRzPBVTVOYVBNZIyeYA/viewform?pli=1');

INSERT INTO landing_spotlights(event_id, image_key) VALUES
(1, 'default.png');

INSERT INTO landing_questions(question, answer) VALUES
($$Who's allowed to join this club?$$, $$ACM@SJSU is open to all SJSU students, regardless of their major!$$),
($$What are the rules of the club?$$, $$Be respectful, keep the clubroom clean, and have fun!$$),
($$Is there a membership fee for the club?$$, $$Yes. It's $20 for 1 semester or $30 for 2 semesters$$),
($$What do I get for a paid membership?$$, $$Paid members are invited to attend exclusive networking sessions, tech talks, and company events. We collaborate with many industry leaders, including Google, Tesla, and Nvidia, so don't miss out!$$);
55 changes: 41 additions & 14 deletions server/src/db/schema.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { boolean, text, timestamp, date, integer, bigint, pgEnum, pgTable, serial, time, numeric, varchar } from 'drizzle-orm/pg-core';

// Enums
export const eventsEnum = pgEnum('events_enum', ['workshop', 'seminar', 'hackathon', 'conference', 'meetup', 'test', 'other']);
export const csFieldsEnum = pgEnum('cs_fields_enum', ['web development', 'machine learning', 'cloud computing', 'artificial intelligence', 'networking', 'cybersecurity', 'mobile development', 'game development', 'data science']);
export const targetAudienceEnum = pgEnum('target_audience_enum', ['students']);
export const equipmentConditionEnum = pgEnum('equipment_condition_enum', ['ready', 'broken', 'in maintenance']);
export const membershipTermEnum = pgEnum('membership_term_enum', ['semester', 'annual']);
export const membershipRequestStatusEnum = pgEnum('membership_request_status_enum', ['pending', 'approved', 'declined']);
export const industryEnum = pgEnum('industry_enum', ['banking and finance', 'aerospace', 'healthcare', 'automotive', 'energy', 'technology']);
export const officerPositionEnum = pgEnum('officer_position_enum', ['president', 'vice president', 'dev team officer', 'treasurer', 'social media manager']);
export const educationLevelEnum = pgEnum('education_level_enum', ['undergraduate', 'graduate']);
export const projectStatusEnum = pgEnum('project_status_enum', ['not started', 'looking for members', 'in progress', 'completed']);
export const eventsEnum = pgEnum('events_enum', ['Workshop', 'seminar', 'Hackathon', 'Conference', 'Meetup', 'Tech Talk', 'Other']);
export const csFieldsEnum = pgEnum('cs_fields_enum', ['Web Development', 'Machine Learning', 'Cloud Computing', 'Artificial Intelligence', 'Networking', 'Cybersecurity', 'Mobile Development', 'Game Development', 'Data Science']);
export const targetAudienceEnum = pgEnum('target_audience_enum', ['Students']);
export const equipmentConditionEnum = pgEnum('equipment_condition_enum', ['Ready', 'Broken', 'In Maintenance']);
export const membershipTermEnum = pgEnum('membership_term_enum', ['Semester', 'Annual']);
export const membershipRequestStatusEnum = pgEnum('membership_request_status_enum', ['Pending', 'Approved', 'Declined']);
export const industryEnum = pgEnum('industry_enum', ['Banking and Finance', 'Aerospace', 'Healthcare', 'Automotive', 'Energy', 'Technology']);
export const officerPositionEnum = pgEnum('officer_position_enum', ['President', 'Vice President', 'Dev Team Officer', 'Treasurer', 'Social Media Manager']);
export const educationLevelEnum = pgEnum('education_level_enum', ['Undergraduate', 'Graduate']);
export const projectStatusEnum = pgEnum('project_status_enum', ['Not Started', 'Looking for Members', 'In Progress', 'Completed']);
export const userRoleEnum = pgEnum('user_role_enum', ['user', 'member', 'admin']);
export const yearEnum = pgEnum('year_enum', ['Freshman', 'Sophomore', 'Junior', 'Senior', 'Alumni']);

// Tables
export const majors = pgTable('majors', {
Expand Down Expand Up @@ -72,7 +73,7 @@ export const equipmentRentals = pgTable('equipment_rentals', {
dateBorrowed: date('date_borrowed').notNull().defaultNow(),
returnDate: date('return_date').notNull(),
price: numeric('price', { precision: 10, scale: 2 }).notNull(),
condition: equipmentConditionEnum('condition').notNull().default('ready'),
condition: equipmentConditionEnum('condition').notNull().default('Ready'),
}, (table) => ({
primaryKey: [table.userId, table.itemId],
}));
Expand Down Expand Up @@ -117,7 +118,7 @@ export const files = pgTable('files', {

export const eventsFiles = pgTable('events_files', {
eventId: integer('event_id').notNull().references(() => events.id, { onUpdate: 'cascade', onDelete: 'cascade' }),
fileKey: text('file_key').notNull().references(() => files.key, { onUpdate: 'cascade', onDelete: 'cascade' }),
fileKey: text('file_key').notNull().references(() => files.key, { onUpdate: 'cascade' }),
}, (table) => ({
primaryKey: [table.eventId, table.fileKey],
}));
Expand Down Expand Up @@ -166,13 +167,13 @@ export const projects = pgTable('projects', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
description: text('description').notNull(),
status: projectStatusEnum('status').notNull().default('not started'),
status: projectStatusEnum('status').notNull().default('Not Started'),
githubLink: text('github_link'),
});

export const projectsFiles = pgTable('projects_files', {
projectId: integer('project_id').notNull().references(() => projects.id, { onUpdate: 'cascade', onDelete: 'cascade' }),
fileKey: text('file_key').notNull().references(() => files.key, { onUpdate: 'cascade', onDelete: 'cascade' }),
fileKey: text('file_key').notNull().references(() => files.key, { onUpdate: 'cascade' }),
}, (table) => ({
primaryKey: [table.projectId, table.fileKey],
}));
Expand Down Expand Up @@ -208,6 +209,26 @@ export const sponsors = pgTable('sponsors', {
logoKey: text('logo_key').notNull(),
});

export const clubLinks = pgTable('club_links', {
id: serial('id').primaryKey(),
instagram: text('instagram'),
discord: text('discord'),
linkedin: text('linkedin'),
memberApplication: text('member_application'),
});

export const landingSpotlights = pgTable('landing_spotlights', {
id: serial('id').primaryKey(),
eventId: integer('event_id').notNull().references(() => events.id, { onUpdate: 'cascade' }),
imageKey: text('image_key').notNull().references(() => files.key, { onUpdate: 'cascade' }),
});

export const landingQuestions = pgTable('landing_questions', {
id: serial('id').primaryKey(),
question: text('question').notNull(),
answer: text('answer').notNull(),
});

// Update types
export type UserKey = typeof userKey.$inferSelect;
export type NewUserKey = typeof userKey.$inferInsert;
Expand Down Expand Up @@ -254,3 +275,9 @@ export type NewMajor = typeof majors.$inferInsert;
export type Session = typeof session.$inferSelect;
export type NewSession = typeof session.$inferInsert;
export type Sponsor = typeof sponsors.$inferInsert;
export type ClubLink = typeof clubLinks.$inferSelect;
export type NewClubLink = typeof clubLinks.$inferInsert;
export type LandingSpotlight = typeof landingSpotlights.$inferSelect;
export type NewLandingSpotlight = typeof landingSpotlights.$inferInsert;
export type LandingQuestion = typeof landingQuestions.$inferSelect;
export type NewLandingQuestion = typeof landingQuestions.$inferInsert;
2 changes: 1 addition & 1 deletion server/src/router/v1/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ authRouter.openapi(
gradDate: new Date().toISOString(),
interests: [],
profilePic: picture,
education_level: 'undergraduate',
education_level: 'Undergraduate',
})
.returning();

Expand Down
Loading

0 comments on commit 7179f32

Please sign in to comment.