diff --git a/assets/js/ProfilePage.jsx b/assets/js/ProfilePage.jsx index 2a5e49db6c536369336f21f84f9ed6c1beb0c9ee..f6ab779ca47c1f8c370924d33742584a995b458d 100644 --- a/assets/js/ProfilePage.jsx +++ b/assets/js/ProfilePage.jsx @@ -29,6 +29,7 @@ export default class ProfilePage extends React.Component { dateOfBirth: '', resume: '', phone_number: '', + portfolio_link: '', show_transcript: '', photo: '', age: '', @@ -45,6 +46,7 @@ export default class ProfilePage extends React.Component { region: '', skills: '', resume: '', + portfolio_link: '', show_transcript: '', volunteer: '', intro: '', @@ -93,6 +95,7 @@ export default class ProfilePage extends React.Component { cityOfBirth: data.birth_place, dateOfBirth: this.parseIndonesianDateFormat(data.birth_date), phone_number: data.phone_number, + portfolio_link: data.portfolio_link, photo: data.photo, show_transcript: data.show_transcript, acceptedNo: data.accepted_no, @@ -276,6 +279,16 @@ export default class ProfilePage extends React.Component { name="linkedin_url" /> </Form.Field> + <Form.Field> + <label htmlFor="portfolio_link">Portfolio Link</label> + <input + onChange={this.handleChange} + placeholder={this.state.portfolio_link === null ? 'https://www.example.com/myproject/' : + this.state.portfolio_link} + defaultValue={this.state.portfolio_link === null ? null : this.state.portfolio_link} + name="portfolio_link" + /> + </Form.Field> <Form.Field> <label htmlFor="website_url">Website URL</label> <input @@ -436,6 +449,17 @@ export default class ProfilePage extends React.Component { </Grid> </Segment> + <Segment basic vertical> + <Grid> + <Grid.Column width={2}> + <Icon name="linkify" size="big" /> + </Grid.Column> + <Grid.Column width={13}> + <a href={this.state.portfolio_link}> {this.state.portfolio_link || 'N/A'} </a> + </Grid.Column> + </Grid> + </Segment> + <Segment basic vertical> <Grid> <Grid.Column width={2}> diff --git a/core/lib/validators.py b/core/lib/validators.py index 54c9b3f35e69f5bb88dffff0514c453181b4904c..01d28fa0b0c17e57345c2b1c61094d99d007d4e9 100755 --- a/core/lib/validators.py +++ b/core/lib/validators.py @@ -44,4 +44,4 @@ def validate_npm(value): raise ValidationError(u"NPM must be 10 digits") val_string = str(value) if sum([3*int(a) for a in val_string[:-1:2]]+[int(a) for a in val_string[1:-1:2]]) % 7 != int(val_string[-1]): - raise ValidationError(u"NPM {} has invalid checksum".format(value)) \ No newline at end of file + raise ValidationError(u"NPM {} has invalid checksum".format(value)) diff --git a/core/migrations/0014_student_portfolio_link.py b/core/migrations/0014_student_portfolio_link.py new file mode 100644 index 0000000000000000000000000000000000000000..a02dad41d9639ba4aa47b38a730a4a4c6e9ab71a --- /dev/null +++ b/core/migrations/0014_student_portfolio_link.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2019-10-06 10:31 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0013_auto_20170602_1130'), + ] + + operations = [ + migrations.AddField( + model_name='student', + name='portfolio_link', + field=models.URLField(blank=True, null=True), + ), + ] diff --git a/core/migrations/0020_merge_20191006_2021.py b/core/migrations/0020_merge_20191006_2021.py new file mode 100644 index 0000000000000000000000000000000000000000..4d7d3284fa5249f3a32e0140c0c37e5079297f05 --- /dev/null +++ b/core/migrations/0020_merge_20191006_2021.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.17 on 2019-10-06 13:21 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0017_vacancy_amount'), + ('core', '0019_merge_20191006_0852'), + ('core', '0014_student_portfolio_link'), + ('core', '0014_auto_20191004_1340'), + ] + + operations = [ + ] diff --git a/core/migrations/0048_merge_20191012_0956.py b/core/migrations/0048_merge_20191012_0956.py new file mode 100644 index 0000000000000000000000000000000000000000..5de42f826bab3b3de2427fbd2262ab57cb47fa9a --- /dev/null +++ b/core/migrations/0048_merge_20191012_0956.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.17 on 2019-10-12 02:56 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0047_merge_20191011_0029'), + ('core', '0020_merge_20191006_2021'), + ] + + operations = [ + ] diff --git a/core/migrations/0055_merge_20191012_1043.py b/core/migrations/0055_merge_20191012_1043.py new file mode 100644 index 0000000000000000000000000000000000000000..971ec999341c2744261f031f4c0bca0ddd3dbcdc --- /dev/null +++ b/core/migrations/0055_merge_20191012_1043.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.17 on 2019-10-12 03:43 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0054_merge_20191012_1018'), + ('core', '0048_merge_20191012_0956'), + ] + + operations = [ + ] diff --git a/core/models/accounts.py b/core/models/accounts.py index 44b37387f534492819be9491ac177661b1b87549..1a66e0debd6afc45524d919e10eb9e71bf3c1686 100644 --- a/core/models/accounts.py +++ b/core/models/accounts.py @@ -77,6 +77,7 @@ class Student(models.Model): show_transcript = models.BooleanField(default=False) self_description = models.CharField(max_length=500, blank=True, db_index=True, null=True) photo = models.FileField(upload_to=get_student_photo_file_path, null=True, blank=True, validators=[validate_image_file_extension]) + portfolio_link = models.URLField(blank=True, null=True) linkedin_url = models.URLField(max_length=200,blank=True, null=True) website_url = models.URLField(max_length=200,blank=True, null=True) region = models.CharField(max_length=30, blank=True, null=True) diff --git a/core/serializers/accounts.py b/core/serializers/accounts.py index fbb6d7ae6b5696b12ead17b1424372f8936d00cc..de1e669d08dc2fb636390739745d2e9af889d578 100644 --- a/core/serializers/accounts.py +++ b/core/serializers/accounts.py @@ -20,7 +20,7 @@ class StudentSerializer(serializers.ModelSerializer): class Meta: model = Student fields = ['id', 'name', 'user', 'npm', 'resume', 'phone_number', 'gender','birth_place', 'birth_date', 'major', 'batch', \ - 'show_transcript', 'photo', 'accepted_no', 'linkedin_url', 'region', 'intro', 'website_url', 'student_gpa', 'age','recommendations', + 'show_transcript', 'photo', 'accepted_no', 'linkedin_url', 'region', 'intro', 'portfolio_link', 'website_url', 'student_gpa', 'age','recommendations', 'latest_work', 'latest_work_desc','read_no', 'volunteer','job_seeking_status', 'skills', 'expected_salary', \ 'self_description', 'github_url'] @@ -53,6 +53,7 @@ class StudentUpdateSerializer(serializers.ModelSerializer): 'region': instance.region, 'photo': photo, 'show_transcript': instance.show_transcript, + 'portfolio_link': instance.portfolio_link, 'self_description': instance.self_description, 'intro': instance.intro, 'expected_salary': instance.expected_salary, @@ -76,6 +77,7 @@ class StudentUpdateSerializer(serializers.ModelSerializer): instance.region = validated_data.get('region', instance.region) instance.photo = validated_data.get('photo', instance.photo) instance.user.email = validated_data.get('email', instance.user.email) + instance.portfolio_link = validated_data.get('portfolio_link', instance.portfolio_link) instance.self_description = validated_data.get('self_description', instance.self_description) instance.intro = validated_data.get('intro', instance.intro) instance.expected_salary = validated_data.get('expected_salary', instance.expected_salary) @@ -95,11 +97,10 @@ class StudentUpdateSerializer(serializers.ModelSerializer): class Meta: model = Student - fields = ['resume', 'email', 'phone_number', 'gender','photo', 'show_transcript', 'linkedin_url', 'region', 'intro', 'website_url', 'student_gpa', + fields = ['resume', 'email', 'phone_number', 'gender','photo', 'show_transcript', 'linkedin_url', 'region', 'intro', 'portfolio_link', 'website_url', 'student_gpa', 'recommendations', 'latest_work', 'latest_work_desc', 'volunteer','job_seeking_status', 'skills', 'expected_salary', \ 'self_description', 'github_url'] - class CompanyUpdateSerializer(serializers.ModelSerializer): def to_representation(self, instance): logo = None diff --git a/core/tests/test_accounts.py b/core/tests/test_accounts.py index da1eae36a5112dbdaa817deb86090a5b4078c05e..5140b33842321ab84839d63c6eb5c41e955ec7f0 100644 --- a/core/tests/test_accounts.py +++ b/core/tests/test_accounts.py @@ -153,7 +153,15 @@ class ProfileUpdateTests(APITestCase): self.assertEqual(response.data.get('phone_number'), '08123123123') url = '/api/students/' + str(student_id) + "/profile/" + response = self.client.patch(url, {'portfolio_link': 'https://www.example.com/myproject'}, format='multipart') + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + self.assertEqual(response.data.get('portfolio_link'), 'https://www.example.com/myproject') + url = '/api/students/' + str(student_id) + "/profile/" + response = self.client.patch(url, {'portfolio_link': 'asdfghjkl'}, format='multipart') + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + + url = '/api/students/' + str(student_id) + "/profile/" response = self.client.patch(url, {'self_description': 'I am very happy'}, format='multipart') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertEqual(response.data.get('self_description'), 'I am very happy') diff --git a/kape/files/student-ui-ux-portofolio/266a3cd8-10d5-479d-891d-cf782f8b1041.pdf b/kape/files/student-ui-ux-portofolio/266a3cd8-10d5-479d-891d-cf782f8b1041.pdf new file mode 100644 index 0000000000000000000000000000000000000000..379cb93fd41385e7ea21e9f02d44b2fb84fd860d Binary files /dev/null and b/kape/files/student-ui-ux-portofolio/266a3cd8-10d5-479d-891d-cf782f8b1041.pdf differ diff --git a/kape/files/student-ui-ux-portofolio/35dc3798-9d40-48e7-9ad9-68a8fe22941e.pdf b/kape/files/student-ui-ux-portofolio/35dc3798-9d40-48e7-9ad9-68a8fe22941e.pdf new file mode 100644 index 0000000000000000000000000000000000000000..379cb93fd41385e7ea21e9f02d44b2fb84fd860d Binary files /dev/null and b/kape/files/student-ui-ux-portofolio/35dc3798-9d40-48e7-9ad9-68a8fe22941e.pdf differ diff --git a/kape/files/student-ui-ux-portofolio/42edb36e-8d01-40d9-91cf-b0d277b285d1.pdf b/kape/files/student-ui-ux-portofolio/42edb36e-8d01-40d9-91cf-b0d277b285d1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..379cb93fd41385e7ea21e9f02d44b2fb84fd860d Binary files /dev/null and b/kape/files/student-ui-ux-portofolio/42edb36e-8d01-40d9-91cf-b0d277b285d1.pdf differ diff --git a/kape/files/student-ui-ux-portofolio/89512de6-4b5e-40cf-a1db-852db95b692d.pdf b/kape/files/student-ui-ux-portofolio/89512de6-4b5e-40cf-a1db-852db95b692d.pdf new file mode 100644 index 0000000000000000000000000000000000000000..379cb93fd41385e7ea21e9f02d44b2fb84fd860d Binary files /dev/null and b/kape/files/student-ui-ux-portofolio/89512de6-4b5e-40cf-a1db-852db95b692d.pdf differ diff --git a/requirements.txt b/requirements.txt index 1c88d9a8b84368998481b916cbeab821bcc372cb..2f71531a4b2f3d4540928e40d42d873c4d72eae9 100755 --- a/requirements.txt +++ b/requirements.txt @@ -13,4 +13,4 @@ django-rest-swagger django-silk requests requests-mock -django-filter==1.1.0 +django-filter==1.1.0 \ No newline at end of file