-
Notifications
You must be signed in to change notification settings - Fork 4
Merge all open feature branches + admin whitelist management #418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
CasperL1218
wants to merge
73
commits into
main
Choose a base branch
from
phase1-all-merges
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
73 commits
Select commit
Hold shift + click to select a range
042e9a8
Finished Landlord Messaging Feature
parsa-tehranipoor 2e9113b
Merged pulled code with current code
parsa-tehranipoor 6c878ad
Fixed minor error-detection bug
parsa-tehranipoor 175c655
Added data tab with apartment data in admin page
CasperL1218 fca6e1c
doc for data tab
CasperL1218 684e0e9
Fixed UX Bugs, display components, and added documentation
parsa-tehranipoor f91602b
Merge branch 'main' into bugs-in-reviews
parsa-tehranipoor 7497b57
add dependencies
CasperL1218 1f98ab2
add export apartment name script
CasperL1218 a85704d
Finishing touches: fixed calendar pop up bug
parsa-tehranipoor 59c7231
Final touches
parsa-tehranipoor 013a576
Final Touches(last one I swear)
parsa-tehranipoor 590a533
Implemented Admin Page Apartment Editing UI\
CasperL1218 9799fa1
Implement folder feature endpoints
dc20dc9
Implement frontend for the folder system
6f508e3
Added more routes plus documentation
parsa-tehranipoor 95c56c7
Update FolderDetailPage to display apartment cards
23f0656
Add documentation for folder api routes
03b8939
Implement folder editing
8b53567
Update apartment removal
c5e6237
Implement clicking into map pins
f7ab07c
Users must submit a review when submitting a new apartment
47945c9
Prompt to add apartment in search results
3fea632
Finished testing, migrated data in firebase, and tweaked routes accor…
parsa-tehranipoor 85b0d8b
Add documentation for Folder components
f5f8c65
Refactor apartment schema to support multiple room types
CasperL1218 f7a2dfb
Implement Room Types Admin UI and Display Utilities
CasperL1218 887d5ca
Implement apartment card display and search filtering for room types
CasperL1218 3831489
Enhance Admin Apartment Data tab with search, filters, and improved l…
CasperL1218 f26cff8
Add Create New Apartment functionality to Admin Data tab
CasperL1218 e2839fe
Fix search UX and improve results page layout
CasperL1218 c7b1f20
Put folders in Bookmarks page
51c4576
Fix fetching apartments
6b373e2
fix routing to saved apartments
70e837c
1. package.json (root):
CasperL1218 afc771f
Files changed:
CasperL1218 fea1cee
format changes
CasperL1218 64c775d
fix lint error
CasperL1218 96f400a
Fixed dependency issues, edited AdminPage to include blog post creati…
parsa-tehranipoor 4a74273
Implement add to folder popover
4be7be0
Implement folder design
c738fe2
Update popover styling
b83326d
Fix repeated re-rendering
5fa50b1
Finalize FolderSection frontend
0ff6c83
Add new developer Parsa Tehranipoor to Contributors list on README file
parsa-tehranipoor 7bcd238
Fix Firebase User import and add Apartment component documentation
CasperL1218 b7c923c
Continued to work on the admin side of the blog post feature via UI f…
parsa-tehranipoor 3d8b6b0
Fix margin for create folder button
1bc0287
Flag deprecated endpoints for saving apartments and landlords
3f221ed
Added documentation to BlogPostPage and BlogPostDetailPage files
parsa-tehranipoor 9e18231
Completed BlogPost Admin page for adding new blogposts
parsa-tehranipoor 456bb39
Update frontend
laurenp-2 c4de3c9
Bulk update of apartment data
laurenp-2 6005238
Update documentation
laurenp-2 e362fb5
Implement unit tests for helper functions
laurenp-2 5a081e7
Fix pre-commit hook: upgrade frontend TS to
CasperL1218 5e37da6
Fix MapInfo JSDoc to follow
CasperL1218 70b5f11
Merge branch 'apartment-component-documentation'
CasperL1218 7dca674
Revert frontend save UI changes — let folder_system branch own that t…
CasperL1218 df939a4
Merge branch 'deprecated-endpoints'
CasperL1218 f211b0b
Merge remote-tracking branch 'origin/data-update'
CasperL1218 4375056
Fix review field helperText using wrong error state, remove unused us…
CasperL1218 e9c4ed7
Merge branch 'bug_fixes'
CasperL1218 2f47189
Fix email endpoint to use req.body, fix error toast severity, remove …
CasperL1218 c58edd9
Merge branch 'bugs-in-reviews'
CasperL1218 c7b50d0
Fix migration to preserve legacy numBeds/numBaths/price as RoomType e…
CasperL1218 f8c2129
Merge branch 'admin-data-edit'
CasperL1218 0ac6b13
Fix Folder type field name: apartmentIds → apartments
CasperL1218 7c8de6c
Merge branch 'folder_system' into main
CasperL1218 e01f91e
Merge main into blog-post-feature; resolve conflicts and prep for merge
CasperL1218 88d3281
Add admin whitelist management feature
CasperL1218 feeef9d
Fix Prettier formatting on authAdmin.ts and LandlordPage.tsx
CasperL1218 417a462
Fix engines node version: 16.x → >=18 to match CI
CasperL1218 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| import axios from 'axios'; | ||
| import * as fs from 'fs'; | ||
| import * as path from 'path'; | ||
|
|
||
| // Define the structure of the API response based on the AdminPage usage | ||
| interface ApartmentData { | ||
| buildingData: { | ||
| id: string; | ||
| name: string; | ||
| address: string; | ||
| area: string; | ||
| numBeds: number; | ||
| numBaths: number; | ||
| landlordId: string; | ||
| photos: string[]; | ||
| urlName: string; | ||
| latitude: number; | ||
| longitude: number; | ||
| distanceToCampus: number; | ||
| }; | ||
| numReviews: number; | ||
| company: string; | ||
| avgRating: number; | ||
| avgPrice: number; | ||
| } | ||
|
|
||
| interface ApiResponse { | ||
| buildingData: ApartmentData[]; | ||
| isEnded: boolean; | ||
| } | ||
|
|
||
| /** | ||
| * Script to export apartment names to a CSV file | ||
| * | ||
| * This script fetches all apartment data from the API endpoint used in AdminPage | ||
| * and exports just the apartment names to a CSV file. | ||
| */ | ||
| const exportApartmentNames = async () => { | ||
| try { | ||
| console.log('Fetching apartment data...'); | ||
|
|
||
| // Use the same API endpoint as AdminPage | ||
| const response = await axios.get<ApiResponse>( | ||
| 'http://localhost:8080/api/page-data/home/1000/numReviews' | ||
| ); | ||
|
|
||
| if (!response.data || !response.data.buildingData) { | ||
| throw new Error('No apartment data received from API'); | ||
| } | ||
|
|
||
| const apartments = response.data.buildingData; | ||
| console.log(`Found ${apartments.length} apartments`); | ||
|
|
||
| // Extract apartment names | ||
| const apartmentNames = apartments.map((apt) => apt.buildingData.name); | ||
|
|
||
| // Create CSV content | ||
| const csvHeader = 'Apartment Name\n'; | ||
| const csvContent = apartmentNames.map((name) => `"${name}"`).join('\n'); | ||
| const fullCsvContent = csvHeader + csvContent; | ||
|
|
||
| // Write to CSV file | ||
| const outputPath = path.join(__dirname, 'apartment_names.csv'); | ||
| fs.writeFileSync(outputPath, fullCsvContent, 'utf8'); | ||
|
|
||
| console.log(`Successfully exported ${apartmentNames.length} apartment names to: ${outputPath}`); | ||
| console.log('First few apartment names:'); | ||
| apartmentNames.slice(0, 5).forEach((name, index) => { | ||
| console.log(`${index + 1}. ${name}`); | ||
| }); | ||
| } catch (error) { | ||
| console.error('Error exporting apartment names:', error); | ||
|
|
||
| if (axios.isAxiosError(error)) { | ||
| if (error.code === 'ECONNREFUSED') { | ||
| console.error( | ||
| 'Could not connect to the server. Make sure the backend server is running on localhost:3000' | ||
| ); | ||
| } else { | ||
| console.error('API request failed:', error.message); | ||
| } | ||
| } | ||
|
|
||
| process.exit(1); | ||
| } | ||
| }; | ||
|
|
||
| // Run the script | ||
| exportApartmentNames(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| import * as fs from 'fs'; | ||
| import * as path from 'path'; | ||
| import { db } from '../src/firebase-config'; | ||
|
|
||
| /** | ||
| * export_apartments.ts | ||
| * | ||
| * Exports all apartment documents from Firestore to a CSV file. | ||
| * The business team can then edit the CSV and pass it to update_apartments_from_csv.ts. | ||
| * | ||
| * Usage: | ||
| * env-cmd -f ../.env.prod ts-node scripts/export_apartments.ts | ||
| * | ||
| * Output: | ||
| * backend/scripts/apartments_export.csv | ||
| */ | ||
|
|
||
| const buildingCollection = db.collection('buildings'); | ||
|
|
||
| // TODO: might have to change header fields or order (talk with business) | ||
| const CSV_HEADERS = [ | ||
| 'id', | ||
| 'name', | ||
| 'address', | ||
| 'landlordId', | ||
| 'numBeds', | ||
| 'numBaths', | ||
| 'price', | ||
| 'area', | ||
| 'latitude', | ||
| 'longitude', | ||
| 'distanceToCampus', | ||
| ]; | ||
|
|
||
| // escape CSV field values | ||
| export const escapeCSVField = (value: unknown): string => { | ||
| const str = value === null || value === undefined ? '' : String(value); | ||
| if (str.includes(',') || str.includes('"') || str.includes('\n')) { | ||
| return `"${str.replace(/"/g, '""')}"`; | ||
| } | ||
| return str; | ||
| }; | ||
|
|
||
| const exportApartments = async () => { | ||
| console.log('Fetching apartments from Firestore...'); | ||
|
|
||
| const snapshot = await buildingCollection.get(); | ||
|
|
||
| if (snapshot.empty) { | ||
| console.log('No apartments found in the database.'); | ||
| process.exit(0); | ||
| } | ||
|
|
||
| console.log(`Found ${snapshot.docs.length} apartments. Writing CSV...`); | ||
|
|
||
| const rows: string[] = [CSV_HEADERS.join(',')]; | ||
|
|
||
| snapshot.docs.forEach((doc) => { | ||
| const data = doc.data(); | ||
| const row = [ | ||
| doc.id, | ||
| data.name, | ||
| data.address, | ||
| data.landlordId, | ||
| data.numBeds, | ||
| data.numBaths, | ||
| data.price, | ||
| data.area, | ||
| data.latitude, | ||
| data.longitude, | ||
| data.distanceToCampus, | ||
| ] | ||
| .map(escapeCSVField) | ||
| .join(','); | ||
|
|
||
| rows.push(row); | ||
| }); | ||
|
|
||
| const outputPath = path.join(__dirname, 'apartments_export.csv'); | ||
| fs.writeFileSync(outputPath, rows.join('\n'), 'utf8'); | ||
|
|
||
| console.log(`Export complete: ${outputPath}`); | ||
| console.log(` ${snapshot.docs.length} apartments exported.`); | ||
| console.log(''); | ||
| console.log('Next steps:'); | ||
| console.log(' 1. Open apartments_export.csv in Excel or Google Sheets'); | ||
| console.log(' 2. Edit the fields you want to update (do NOT change the id column)'); | ||
| console.log(' 3. Save as CSV'); | ||
| console.log(' 4. Run: env-cmd -f ../.env.prod ts-node scripts/update_apartments_from_csv.ts'); | ||
|
|
||
| process.exit(0); | ||
| }; | ||
|
|
||
| if (require.main === module) { | ||
| exportApartments().catch((err) => { | ||
| console.error('Export failed:', err); | ||
| process.exit(1); | ||
| }); | ||
| } | ||
|
|
||
| export default exportApartments; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| /** | ||
| * init_blogposts_collection.ts | ||
| * | ||
| * One-time idempotent script to ensure the `blogposts` Firestore collection exists | ||
| * with the correct schema. Creates a sentinel document if the collection is empty. | ||
| * | ||
| * Safe to run multiple times — never overwrites existing documents. | ||
| * | ||
| * Usage: ts-node scripts/init_blogposts_collection.ts | ||
| */ | ||
|
|
||
| import { db } from '../src/firebase-config'; | ||
|
|
||
| const blogPostCollection = db.collection('blogposts'); | ||
|
|
||
| const initBlogPostsCollection = async (): Promise<void> => { | ||
| console.log('Checking blogposts collection...'); | ||
|
|
||
| const snapshot = await blogPostCollection.limit(1).get(); | ||
|
|
||
| if (!snapshot.empty) { | ||
| console.log(`Collection already has ${snapshot.size}+ document(s). No initialization needed.`); | ||
| return; | ||
| } | ||
|
|
||
| console.log('Collection is empty. Creating sentinel document...'); | ||
|
|
||
| const sentinelDoc = blogPostCollection.doc('_init'); | ||
| const existing = await sentinelDoc.get(); | ||
|
|
||
| if (existing.exists) { | ||
| console.log('Sentinel document already exists. Done.'); | ||
| return; | ||
| } | ||
|
|
||
| await sentinelDoc.set({ | ||
| title: '[INIT] Collection initialized', | ||
| content: '', | ||
| blurb: '', | ||
| date: new Date(), | ||
| tags: [], | ||
| visibility: 'DELETED', | ||
| likes: 0, | ||
| saves: 0, | ||
| coverImageUrl: '', | ||
| userId: null, | ||
| }); | ||
|
|
||
| console.log('Sentinel document created at blogposts/_init with visibility=DELETED.'); | ||
| console.log('Collection is ready. This sentinel document is safe to delete.'); | ||
| }; | ||
|
|
||
| initBlogPostsCollection() | ||
| .then(() => { | ||
| console.log('Done.'); | ||
| process.exit(0); | ||
| }) | ||
| .catch((err) => { | ||
| console.error('Error initializing blogposts collection:', err); | ||
| process.exit(1); | ||
| }); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure to note this as a breaking change in the PR description (I got dependency version issues with ts-node and a few other dependencies as a result)