Search Companies

Search for Jobs
main
David 2023-06-20 03:23:54 +02:00
parent bfa24bec37
commit 8b0c44e35b
7 changed files with 356 additions and 75 deletions

View File

@ -1,21 +1,23 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.SENDTO"/>
<application <application
android:label="cpd_ss23" android:label="cpd_ss23"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"

View File

@ -1,16 +1,15 @@
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart'; import 'package:url_launcher/url_launcher_string.dart';
import '../Widgets/bottom_nav_bar.dart'; import '../Widgets/bottom_nav_bar.dart';
import '../services/global_variables.dart'; import '../services/global_variables.dart';
class ProfileScreen extends StatefulWidget { class ProfileScreen extends StatefulWidget {
final String userId; final String userID;
const ProfileScreen({required this.userId}); const ProfileScreen({required this.userID});
@override @override
State<ProfileScreen> createState() => _ProfileScreenState(); State<ProfileScreen> createState() => _ProfileScreenState();
@ -63,7 +62,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
final DocumentSnapshot userDoc = await FirebaseFirestore.instance final DocumentSnapshot userDoc = await FirebaseFirestore.instance
.collection('users') .collection('users')
.doc(widget.userId) .doc(widget.userID)
.get(); .get();
if (userDoc.exists) { if (userDoc.exists) {
@ -84,7 +83,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
User? user = _auth.currentUser; User? user = _auth.currentUser;
final _uid = user!.uid; final _uid = user!.uid;
setState(() { setState(() {
_isSameUser = _uid == widget.userId; _isSameUser = _uid == widget.userID;
}); });
} else { } else {
print('User not found'); print('User not found');
@ -119,7 +118,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
// Update data in Firebase // Update data in Firebase
if (_isSameUser) { if (_isSameUser) {
_firestore.collection('users').doc(widget.userId).update({ _firestore.collection('users').doc(widget.userID).update({
'name': name, 'name': name,
'email': email, 'email': email,
'phone': phoneNumber, 'phone': phoneNumber,
@ -136,7 +135,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text('Profile'), title: const Text('Profile'),
actions: [ actions: [
if (_isSameUser) if (_isSameUser)
ElevatedButton( ElevatedButton(
@ -150,7 +149,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
Colors.white, Colors.white,
), ),
padding: MaterialStateProperty.all<EdgeInsets>( padding: MaterialStateProperty.all<EdgeInsets>(
EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
), ),
shape: MaterialStateProperty.all<RoundedRectangleBorder>( shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder( RoundedRectangleBorder(
@ -162,7 +161,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
if (!_isSameUser && email != null) if (!_isSameUser && email != null)
IconButton( IconButton(
onPressed: _sendEmail, onPressed: _sendEmail,
icon: Icon(Icons.mail), icon: const Icon(Icons.mail),
), ),
], ],
), ),
@ -188,85 +187,85 @@ class _ProfileScreenState extends State<ProfileScreen> {
SingleChildScrollView( SingleChildScrollView(
child: Column( child: Column(
children: [ children: [
SizedBox(height: 40), const SizedBox(height: 40),
Container( Container(
width: MediaQuery.of(context).size.width , width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width , height: MediaQuery.of(context).size.width,
decoration: BoxDecoration( decoration: const BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: ClipOval( child: ClipOval(
child: imageUrl != null child: imageUrl != null
? Image.network( ? Image.network(
imageUrl!, imageUrl!,
fit: BoxFit.cover, fit: BoxFit.cover,
) )
: Image.asset( : Image.asset(
'assets/images/signup.png', 'assets/images/signup.png',
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
), ),
SizedBox(height: 24), const SizedBox(height: 24),
Padding( Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text( const Text(
'Name:', 'Name:',
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 18, fontSize: 18,
), ),
), ),
SizedBox(height: 4), const SizedBox(height: 4),
_isEditing && _isSameUser _isEditing && _isSameUser
? TextFormField( ? TextFormField(
controller: _nameController, controller: _nameController,
) )
: Text(name ?? ''), : Text(name ?? ''),
SizedBox(height: 16), const SizedBox(height: 16),
Text( const Text(
'Email:', 'Email:',
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 18, fontSize: 18,
), ),
), ),
SizedBox(height: 4), const SizedBox(height: 4),
_isEditing && _isSameUser _isEditing && _isSameUser
? TextFormField( ? TextFormField(
controller: _emailController, controller: _emailController,
) )
: Text(email ?? ''), : Text(email ?? ''),
SizedBox(height: 16), const SizedBox(height: 16),
Text( const Text(
'Phone Number:', 'Phone Number:',
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 18, fontSize: 18,
), ),
), ),
SizedBox(height: 4), const SizedBox(height: 4),
_isEditing && _isSameUser _isEditing && _isSameUser
? TextFormField( ? TextFormField(
controller: _phoneNumberController, controller: _phoneNumberController,
) )
: Text(phoneNumber ?? ''), : Text(phoneNumber ?? ''),
SizedBox(height: 16), const SizedBox(height: 16),
Text( const Text(
'Location:', 'Location:',
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 18, fontSize: 18,
), ),
), ),
SizedBox(height: 4), const SizedBox(height: 4),
_isEditing && _isSameUser _isEditing && _isSameUser
? TextFormField( ? TextFormField(
controller: _locationController, controller: _locationController,
) )
: Text(location ?? ''), : Text(location ?? ''),
], ],
), ),
@ -277,7 +276,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
if (_isLoading) if (_isLoading)
Container( Container(
color: Colors.black.withOpacity(0.5), color: Colors.black.withOpacity(0.5),
child: Center( child: const Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
), ),
), ),

View File

@ -1,39 +1,114 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:cpd_ss23/Widgets/all_companies_widget.dart';
import 'package:cpd_ss23/Widgets/bottom_nav_bar.dart'; import 'package:cpd_ss23/Widgets/bottom_nav_bar.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AllWorkersScreen extends StatefulWidget { class AllWorkersScreen extends StatefulWidget {
@override @override
State<AllWorkersScreen> createState() => _AllWorkersScreenState(); State<AllWorkersScreen> createState() => _AllWorkersScreenState();
} }
class _AllWorkersScreenState extends State<AllWorkersScreen> { class _AllWorkersScreenState extends State<AllWorkersScreen> {
final TextEditingController _searchQueryController = TextEditingController();
String searchQuery = 'Search Query';
Widget _buildSearchField() {
return TextField(
controller: _searchQueryController,
autocorrect: true,
decoration: const InputDecoration(
hintText: "Search for companies...",
border: InputBorder.none,
hintStyle: TextStyle(color: Colors.white),
),
style: const TextStyle(color: Colors.white, fontSize: 16.0),
onChanged: (query) => updateSearchQuery(query),
);
}
List<Widget> _buildActions() {
return <Widget>[
IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
_clearSearchQuery();
},
)
];
}
void _clearSearchQuery() {
setState(() {
_searchQueryController.clear();
updateSearchQuery("");
});
}
void updateSearchQuery(String newQuery) {
setState(() {
searchQuery = newQuery;
print(searchQuery);
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
decoration: const BoxDecoration( decoration: const BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(
colors: [Colors.cyan, Colors.white60], colors: [Colors.cyan, Colors.white60],
begin: Alignment.centerLeft, begin: Alignment.centerLeft,
end: Alignment.centerRight, end: Alignment.centerRight,
stops: [0.2, 0.9], stops: [0.2, 0.9],
) )
), ),
child: Scaffold( child: Scaffold(
bottomNavigationBar: BottomNavigationBarForApp(indexNum: 1,), bottomNavigationBar: BottomNavigationBarForApp(
indexNum: 1,
),
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
appBar: AppBar( appBar: AppBar(
backgroundColor: Colors.cyan, backgroundColor: Colors.cyan,
title: const Text('All Workers Screen'), automaticallyImplyLeading: false,
actions: [ title: _buildSearchField(),
IconButton( actions: _buildActions(),
icon: const Icon(Icons.search), ),
onPressed: () { body: StreamBuilder<QuerySnapshot>(
// Action when the search icon is clicked stream: FirebaseFirestore.instance
}, .collection("users")
), .where("name", isGreaterThanOrEqualTo: searchQuery)
], .snapshots(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.connectionState == ConnectionState.active) {
if (snapshot.data!.docs.isNotEmpty) {
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (BuildContext context, int index) {
return AllWorkersWidget(
userID: snapshot.data!.docs[index]["id"],
userName: snapshot.data!.docs[index]["name"],
userEmail: snapshot.data!.docs[index]["email"],
phoneNumber: snapshot.data!.docs[index]["phone"],
userImageUrl: snapshot.data!.docs[index]["userImage"],
);
});
} else {
return const Center(
child: Text("There is no user."),
);
}
}
return const Center(
child: Text(
"Something went wrong",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
),
);
},
), ),
), ),
); );

View File

@ -1,11 +1,57 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:cpd_ss23/Widgets/job_widget.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../jobs/jobs_screen.dart';
class SearchScreen extends StatefulWidget { class SearchScreen extends StatefulWidget {
@override @override
State<SearchScreen> createState() => _SearchScreenState(); State<SearchScreen> createState() => _SearchScreenState();
} }
class _SearchScreenState extends State<SearchScreen> { class _SearchScreenState extends State<SearchScreen> {
final TextEditingController _searchQueryController = TextEditingController();
String searchQuery = 'Search Query';
Widget _buildSearchField() {
return TextField(
controller: _searchQueryController,
autocorrect: true,
decoration: const InputDecoration(
hintText: "Search for jobs...",
border: InputBorder.none,
hintStyle: TextStyle(color: Colors.white),
),
style: const TextStyle(color: Colors.white, fontSize: 16.0),
onChanged: (query) => updateSearchQuery(query),
);
}
List<Widget> _buildActions() {
return <Widget>[
IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
_clearSearchQuery();
},
)
];
}
void _clearSearchQuery() {
setState(() {
_searchQueryController.clear();
updateSearchQuery("");
});
}
void updateSearchQuery(String newQuery) {
setState(() {
searchQuery = newQuery;
print(searchQuery);
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
@ -18,7 +64,7 @@ class _SearchScreenState extends State<SearchScreen> {
child: Scaffold( child: Scaffold(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
appBar: AppBar( appBar: AppBar(
title: const Text("Search Job Screen"), title: _buildSearchField(),
centerTitle: true, centerTitle: true,
flexibleSpace: Container( flexibleSpace: Container(
decoration: const BoxDecoration( decoration: const BoxDecoration(
@ -28,6 +74,57 @@ class _SearchScreenState extends State<SearchScreen> {
end: Alignment.centerRight, end: Alignment.centerRight,
stops: [0.2, 0.9])), stops: [0.2, 0.9])),
), ),
leading: IconButton(
onPressed: () {
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => JobScreen()));
},
icon: const Icon(Icons.arrow_back),
),
actions: _buildActions(),
),
body: StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance
.collection("jobs")
.where("jobTitle", isGreaterThanOrEqualTo: searchQuery)
.where("recruitment", isEqualTo: true)
.snapshots(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.connectionState == ConnectionState.active) {
if (snapshot.data?.docs.isNotEmpty == true) {
return ListView.builder(
itemCount: snapshot.data?.docs.length,
itemBuilder: (BuildContext context, int index) {
return JobWidget(
jobTitle: snapshot.data?.docs[index]["jobTitle"],
jobDescription: snapshot.data?.docs[index]
["jobDescription"],
jobId: snapshot.data?.docs[index]["jobId"],
uploadedBy: snapshot.data?.docs[index]["uploadedBy"],
userImage: snapshot.data?.docs[index]["userImage"],
name: snapshot.data?.docs[index]["name"],
recruitment: snapshot.data?.docs[index]["recruitment"],
email: snapshot.data?.docs[index]["email"],
location: snapshot.data?.docs[index]["location"]);
},
);
} else {
return const Center(
child: Text("There is no Job"),
);
}
}
return const Center(
child: Text(
"Something went wrong",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30.0),
),
);
},
), ),
), ),
); );

View File

@ -0,0 +1,103 @@
import 'package:cpd_ss23/Search/profile_company.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher_string.dart';
class AllWorkersWidget extends StatefulWidget {
final String userID;
final String userName;
final String userEmail;
final String phoneNumber;
final String userImageUrl;
const AllWorkersWidget({
required this.userID,
required this.userName,
required this.userEmail,
required this.phoneNumber,
required this.userImageUrl,
});
@override
State<AllWorkersWidget> createState() => _AllWorkersWidgetState();
}
class _AllWorkersWidgetState extends State<AllWorkersWidget> {
void _mailTo() async {
var mailUrl = "mailto: ${widget.userEmail}";
print("widget.userEmail ${widget.userEmail}");
if (await canLaunchUrlString(mailUrl)) {
await launchUrlString(mailUrl);
} else {
print("error");
throw "Error Occured";
}
}
@override
Widget build(BuildContext context) {
return Card(
elevation: 8,
color: Colors.white10,
margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 6),
child: ListTile(
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => ProfileScreen(userID: widget.userID)));
},
contentPadding:
const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
leading: Container(
padding: const EdgeInsets.only(right: 12),
decoration: const BoxDecoration(
border: Border(
right: BorderSide(width: 1),
),
),
child: CircleAvatar(
backgroundColor: Colors.transparent,
radius: 20,
child: Image.network(widget.userImageUrl == null
? "https://st4.depositphotos.com/4329009/19956/v/600/depositphotos_199564354-stock-illustration-creative-vector-illustration-default-avatar.jpg"
: widget.userImageUrl),
),
),
title: Text(
widget.userName,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
subtitle: const Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Visit Profile",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.grey,
),
)
],
),
trailing: IconButton(
icon: const Icon(
Icons.mail_outline,
size: 30,
color: Colors.grey,
),
onPressed: () {
_mailTo();
},
),
),
);
}
}

View File

@ -5,6 +5,7 @@ import 'package:cpd_ss23/user_state.dart';
import 'package:curved_navigation_bar/curved_navigation_bar.dart'; import 'package:curved_navigation_bar/curved_navigation_bar.dart';
import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../jobs/jobs_screen.dart'; import '../jobs/jobs_screen.dart';
class BottomNavigationBarForApp extends StatelessWidget { class BottomNavigationBarForApp extends StatelessWidget {
@ -94,11 +95,12 @@ class BottomNavigationBarForApp extends StatelessWidget {
} else if (index == 2){ } else if (index == 2){
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => UploadJobNow())); Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => UploadJobNow()));
} else if (index == 3){ } else if (index == 3){
final FirebaseAuth _auth=FirebaseAuth.instance; final FirebaseAuth _auth = FirebaseAuth.instance;
final User? user = _auth.currentUser; final User? user = _auth.currentUser;
final String uid = user!.uid; final String uid = user!.uid;
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => ProfileScreen(userId: uid))); Navigator.pushReplacement(context,
} MaterialPageRoute(builder: (_) => ProfileScreen(userID: uid)));
}
else if (index == 4){ else if (index == 4){
_logout(context); _logout(context);
} }

View File

@ -1,5 +1,4 @@
import 'package:cpd_ss23/Search/profile_company.dart'; import 'package:cpd_ss23/Search/profile_company.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class CommentWidget extends StatefulWidget { class CommentWidget extends StatefulWidget {
@ -26,7 +25,11 @@ class _CommentWidgetState extends State<CommentWidget> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InkWell( return InkWell(
onTap: () { onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context)=> ProfileScreen(userId: widget.commenterId))); Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ProfileScreen(userID: widget.commenterId)));
}, },
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(