Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .idea/deploymentTargetDropDown.xml

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

7 changes: 7 additions & 0 deletions .idea/misc.xml

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

192 changes: 192 additions & 0 deletions Backend_HandyHelper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,198 @@ app.put('/users/:username/contact', (req, res) => {
});
});

// Define a route to retrieve the requests
app.get('/requests', (req, res) => {
// Query to retrieve the requests
const query = `SELECT post.title, post.initial_price, post.content, post.service_date, users.username, users.rating FROM apply INNER JOIN post ON apply.post_id = post.id INNER JOIN users ON apply.national_id = users.national_id`;

// Execute the query
connection.query(query, (error, results) => {
if (error) {
console.error('Error retrieving requests:', error);
res.status(500).json({ error: 'Failed to retrieve requests' });
} else {
res.json(results);
}
});
});

// API endpoint to retrieve the number of applications for each request
app.get('/numOfApplicants', (req, res) => {
const query = `
SELECT post.id, post.title, COUNT(apply.post_id) AS num_applications
FROM post
LEFT JOIN apply ON post.id = apply.post_id AND apply.accepted_status <> 'R'
GROUP BY post.id, post.title
`;

connection.query(query, (err, results) => {
if (err) {
console.error('Error executing query:', err);
res.status(500).json({ error: 'An error occurred' });
} else {
res.json(results);
}
});
});

app.get('/combinedData/:nationalID', (req, res) => {
const nationalID = req.params.nationalID;

const query = `
SELECT
post.title, post.initial_price, post.content, post.service_date, post.id,
users.username, users.rating,
COUNT(CASE WHEN apply.accepted_status <> 'R' THEN 1 END) AS num_applications,
EXISTS (
SELECT 1
FROM apply
WHERE apply.post_id = post.id
AND apply.accepted_status = 'A'
LIMIT 1
) AS has_accepted_applicant
FROM
post
LEFT JOIN
apply ON post.id = apply.post_id
INNER JOIN
users ON post.national_id = users.national_id
WHERE
post.national_id = ?
GROUP BY
post.title, post.initial_price, post.content, post.id, post.service_date, users.username, users.rating
ORDER BY
post.service_date DESC
`;

connection.query(query, [nationalID], (err, results) => {
if (err) {
console.error('Error executing query:', err);
res.status(500).json({ error: 'An error occurred' });
} else {
res.json(results);
}
});
});


// Define the route for retrieving applicants based on post ID
app.get('/applicants/:postId', (req, res) => {
const postId = req.params.postId;

// Execute the SQL query to fetch applicants
const query = `
SELECT users.username, users.email, users.rating, users.image, users.national_id, apply.apply_at, apply.accepted_status, apply.apply_price
FROM apply
JOIN users ON users.national_id = apply.national_id
WHERE apply.post_id = ? AND apply.accepted_status != 'R'
`;

// Execute the query with the post ID as a parameter
connection.query(query, [postId], (error, results) => {
if (error) {
console.error('Error retrieving applicants:', error);
res.status(500).json({ error: 'An error occurred while retrieving applicants.' });
} else {
// Return the applicants as a JSON response
res.json(results);
}
});
});


app.post('/updateApplicationStatus', (req, res) => {
const { national_id, post_id, status } = req.body;
const query = `
UPDATE
apply
SET
accepted_status = ?
WHERE
national_id = ?
AND post_id = ?
`;

connection.query(query, [status, national_id, post_id], (error) => {
if (error) {
console.error('Error updating application status:', error);
res.sendStatus(500);
} else {
res.sendStatus(200);
}
});
});
app.post('/createPost', (req, res) => {
const { national_id, title, location_lat, location_lon, date, time, compensation, description } = req.body;

// Construct the SQL query
const query = `
INSERT INTO post (title, content, created_at, national_id, service_date, service_time, location_lat, location_lon, initial_price)
VALUES (?, ?, NOW(), ?, ?, ?, ?, ?, ?)
`;

// Execute the query
connection.query(query, [title, description, national_id, date, time, location_lat, location_lon, compensation], (error, results) => {
if (error) {
console.error('Error creating post:', error);
res.sendStatus(500);
} else {
res.sendStatus(200);
}
});
});


app.get('/getApplicationStatus', (req, res) => {
const national_id = req.query.national_id;
const post_id = req.query.post_id;
const query = `
SELECT accepted_status
FROM apply
WHERE national_id = ?
AND post_id = ?
`;

connection.query(query, [national_id, post_id], (error, results) => {
if (error) {
console.error('Error retrieving application status:', error);
res.sendStatus(500);
} else {
if (results.length > 0) {
const acceptedStatus = results[0].accepted_status;
res.status(200).json({ acceptedStatus });
} else {
res.status(404).json({ message: 'Application not found' });
}
}
});
});

// Retrieve the posts that the user applied to along with the count of non-rejected applications, ordered by service_date
app.get('/appliedPosts/:userId', (req, res) => {
const userId = req.params.userId;

const query = `
SELECT post.id, post.title, post.content, post.service_date, post.service_time, post.location_lat, post.location_lon, post.category, post.initial_price, post.state, apply.accepted_status,
COUNT(CASE WHEN apply.accepted_status != 'R' THEN 1 END) AS num_applications
FROM post
INNER JOIN apply ON post.id = apply.post_id
WHERE apply.national_id = ?
GROUP BY post.id
ORDER BY post.service_date ASC
`;

connection.query(query, [userId], (error, results) => {
if (error) {
console.error('Error retrieving applied posts:', error);
res.status(500).json({ error: 'Failed to retrieve applied posts' });
} else {
res.json(results);
}
});
});




app.listen(3000, () => console.log('Server started'));
Expand Down
6 changes: 5 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ android {
defaultConfig {
applicationId "com.mariam.registeration"
minSdk 26
targetSdk 33
targetSdk 34
versionCode 1
versionName "1.0"

Expand Down Expand Up @@ -41,4 +41,8 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation 'com.google.android.gms:play-services-maps:18.1.0'
implementation 'com.google.android.libraries.places:places:3.2.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}
105 changes: 37 additions & 68 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,94 +2,63 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-feature
android:name="android.hardware.telephony"
android:required="false" />

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@style/Theme.Registeration"
tools:targetApi="31">
<activity

android:name=".AppliedActivity"
android:exported="false"/>
<activity
android:name=".register_done"
android:exported="false" />
<activity
android:name=".description"
android:exported="false" />
<activity
android:name=".setup_interest"
android:exported="false" />
<activity
android:name=".verify_phone2"
android:exported="false" />
<activity
android:name=".verify_phone"
tools:targetApi="31"
android:networkSecurityConfig="@xml/network_security_config">

android:exported="false" />
<activity
android:name=".RequestDetailsActivity"
android:windowSoftInputMode="adjustPan"
android:exported="false"
/>
<activity
android:name=".FilterActivity"
android:exported="false"
android:theme="@style/Theme.MaterialComponents.Light.NoActionBar" />
<activity
android:name=".HomeActivity"
android:exported="false" />
<activity
android:name=".Login"
android:exported="false" />
<activity
android:name=".SignUp"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<!-- Activities -->
<activity android:name=".AppliedActivity" android:exported="false" />
<activity android:name=".register_done" android:exported="false" />
<activity android:name=".description" android:exported="false" />
<activity android:name=".setup_interest" android:exported="false" />
<activity android:name=".verify_phone2" android:exported="false" />
<activity android:name=".verify_phone" android:exported="false" />
<activity android:name=".RequestDetailsActivity" android:windowSoftInputMode="adjustPan" android:exported="false" />
<activity android:name=".FilterActivity" android:exported="false" android:theme="@style/Theme.MaterialComponents.Light.NoActionBar" />
<activity android:name=".HomeActivity" android:exported="false" />
<activity android:name=".Login" android:exported="false" />
<activity android:name=".SignUp" android:exported="false" />
<activity android:name=".MyApplications" android:exported="false" />
<activity android:name=".PostService" android:exported="false" />
<activity android:name=".CreatePost" android:exported="false" />
<activity android:name=".PostConfirmation" android:exported="false" />
<activity android:name=".Applicants" android:exported="false" />
<activity android:name=".Accepted" android:exported="false" />
<activity android:name=".MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ProfileMain"
android:exported="false" />
<activity
android:name=".ProfileWallet"
android:exported="false" />
<activity
android:name=".ProfileSettings"
android:exported="false" />
<activity
android:name=".AccountInfo"
android:exported="false" />
<activity
android:name=".ChangePassword"
android:exported="false" />
<activity
android:name=".CustomerSupportMain"
android:exported="false" />
<activity
android:name=".EnlargedProfilePicture"
android:theme="@style/Theme.MaterialComponents.Light.NoActionBar" />
<activity android:name=".ProfileMain" android:exported="false" />
<activity android:name=".ProfileWallet" android:exported="false" />
<activity android:name=".ProfileSettings" android:exported="false" />
<activity android:name=".AccountInfo" android:exported="false" />
<activity android:name=".ChangePassword" android:exported="false" />
<activity android:name=".CustomerSupportMain" android:exported="false" />
<activity android:name=".MyRequests" android:exported="false" />
<activity android:name=".EnlargedProfilePicture" android:theme="@style/Theme.MaterialComponents.Light.NoActionBar" />

<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
android:value="AIzaSyAAUKNLUrCJGc3UijGGKO6wz3VIloVlbRU" />
</application>

</manifest>
</manifest>
Binary file added app/src/main/ic_launcher-playstore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading